001: /*
002: * Licensed to the Apache Software Foundation (ASF) under one
003: * or more contributor license agreements. See the NOTICE file
004: * distributed with this work for additional information
005: * regarding copyright ownership. The ASF licenses this file
006: * to you under the Apache License, Version 2.0 (the
007: * "License"); you may not use this file except in compliance
008: * with the License. You may obtain a copy of the License at
009: *
010: * http://www.apache.org/licenses/LICENSE-2.0
011: *
012: * Unless required by applicable law or agreed to in writing,
013: * software distributed under the License is distributed on an
014: * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
015: * KIND, either express or implied. See the License for the
016: * specific language governing permissions and limitations
017: * under the License.
018: */
019:
020: package org.apache.geronimo.jetty6.handler;
021:
022: import java.io.IOException;
023:
024: import javax.servlet.ServletException;
025: import javax.servlet.http.HttpServletRequest;
026: import javax.servlet.http.HttpServletResponse;
027: import javax.transaction.Status;
028: import javax.transaction.SystemException;
029: import javax.transaction.UserTransaction;
030:
031: import org.mortbay.jetty.Handler;
032:
033: /**
034: * @version $Rev: 601149 $ $Date: 2007-12-04 15:30:18 -0800 (Tue, 04 Dec 2007) $
035: */
036: public class UserTransactionHandler extends AbstractImmutableHandler {
037: private final UserTransaction userTransaction;
038:
039: public UserTransactionHandler(Handler next,
040: UserTransaction userTransaction) {
041: super (next);
042: this .userTransaction = userTransaction;
043: }
044:
045: public void handle(String target, HttpServletRequest request,
046: HttpServletResponse response, int dispatch)
047: throws IOException, ServletException {
048: boolean active = isActive();
049: try {
050: next.handle(target, request, response, dispatch);
051: } finally {
052: if ((!active && isMarkedRollback())
053: || (dispatch == REQUEST && isActive())) {
054: try {
055: userTransaction.rollback();
056: } catch (SystemException e) {
057: throw new ServletException(
058: "Error rolling back transaction left open by user program",
059: e);
060: }
061: }
062: }
063: }
064:
065: public void lifecycleCommand(LifecycleCommand lifecycleCommand)
066: throws Exception {
067: boolean active = isActive();
068: try {
069: super .lifecycleCommand(lifecycleCommand);
070: } finally {
071: if (!active && isActive()) {
072: try {
073: userTransaction.rollback();
074: } catch (SystemException e) {
075: throw new ServletException(
076: "Error rolling back transaction left open by user program",
077: e);
078: }
079: }
080: }
081: }
082:
083: private boolean isActive() throws ServletException {
084: try {
085: return !(userTransaction.getStatus() == Status.STATUS_NO_TRANSACTION || userTransaction
086: .getStatus() == Status.STATUS_COMMITTED);
087: } catch (SystemException e) {
088: throw new ServletException(
089: "Could not determine transaction status", e);
090: }
091: }
092:
093: private boolean isMarkedRollback() throws ServletException {
094: try {
095: return userTransaction.getStatus() == Status.STATUS_MARKED_ROLLBACK;
096: } catch (SystemException e) {
097: throw new ServletException(
098: "Could not determine transaction status", e);
099: }
100: }
101: }
|