01: /*
02: * Licensed to the Apache Software Foundation (ASF) under one
03: * or more contributor license agreements. See the NOTICE file
04: * distributed with this work for additional information
05: * regarding copyright ownership. The ASF licenses this file
06: * to you under the Apache License, Version 2.0 (the
07: * "License"); you may not use this file except in compliance
08: * with the License. You may obtain a copy of the License at
09: *
10: * http://www.apache.org/licenses/LICENSE-2.0
11: *
12: * Unless required by applicable law or agreed to in writing,
13: * software distributed under the License is distributed on an
14: * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15: * KIND, either express or implied. See the License for the
16: * specific language governing permissions and limitations
17: * under the License.
18: */
19: package org.apache.geronimo.tomcat.interceptor;
20:
21: import javax.servlet.ServletRequest;
22: import javax.servlet.ServletResponse;
23: import javax.transaction.Status;
24: import javax.transaction.SystemException;
25: import javax.transaction.UserTransaction;
26:
27: import org.apache.commons.logging.Log;
28: import org.apache.commons.logging.LogFactory;
29:
30: public class UserTransactionBeforeAfter implements BeforeAfter {
31: private static Log log = LogFactory
32: .getLog(UserTransactionBeforeAfter.class);
33:
34: private final UserTransaction userTransaction;
35:
36: private final BeforeAfter next;
37:
38: private final int index;
39:
40: public UserTransactionBeforeAfter(BeforeAfter next, int index,
41: UserTransaction userTransaction) {
42: this .next = next;
43: this .index = index;
44: this .userTransaction = userTransaction;
45: }
46:
47: public void after(Object[] context, ServletRequest httpRequest,
48: ServletResponse httpResponse, int dispatch) {
49: if (next != null) {
50: next.after(context, httpRequest, httpResponse, dispatch);
51: }
52:
53: boolean active = (Boolean) context[index];
54: if ((!active && isMarkedRollback())
55: || (dispatch == EDGE_SERVLET && isActive())) {
56: try {
57: userTransaction.rollback();
58: } catch (SystemException e) {
59: throw new RuntimeException(
60: "Error rolling back transaction left open by user program",
61: e);
62: }
63: }
64:
65: }
66:
67: public void before(Object[] context, ServletRequest request,
68: ServletResponse response, int dispatch) {
69: context[index] = isActive();
70: next.before(context, request, response, dispatch);
71: }
72:
73: private boolean isActive() {
74: try {
75: return !(userTransaction.getStatus() == Status.STATUS_NO_TRANSACTION || userTransaction
76: .getStatus() == Status.STATUS_COMMITTED);
77: } catch (SystemException e) {
78: log.error("Could not determine transaction status", e);
79: throw new RuntimeException(
80: "Could not determine transaction status", e);
81: }
82: }
83:
84: private boolean isMarkedRollback() {
85: try {
86: return userTransaction.getStatus() == Status.STATUS_MARKED_ROLLBACK;
87: } catch (SystemException e) {
88: log.error("Could not determine transaction status", e);
89: throw new RuntimeException(
90: "Could not determine transaction status", e);
91: }
92: }
93: }
|