1 /*** 2 * 3 * Copyright 2005 LogicBlaze, Inc. 4 * 5 * Licensed under the Apache License, Version 2.0 (the "License"); 6 * you may not use this file except in compliance with the License. 7 * You may obtain a copy of the License at 8 * 9 * http://www.apache.org/licenses/LICENSE-2.0 10 * 11 * Unless required by applicable law or agreed to in writing, software 12 * distributed under the License is distributed on an "AS IS" BASIS, 13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 * See the License for the specific language governing permissions and 15 * limitations under the License. 16 * 17 **/ 18 package org.jencks; 19 20 import org.apache.commons.logging.Log; 21 import org.apache.commons.logging.LogFactory; 22 23 import javax.jms.Message; 24 import javax.jms.MessageListener; 25 import javax.resource.ResourceException; 26 import javax.resource.spi.endpoint.MessageEndpoint; 27 import javax.transaction.HeuristicMixedException; 28 import javax.transaction.HeuristicRollbackException; 29 import javax.transaction.NotSupportedException; 30 import javax.transaction.RollbackException; 31 import javax.transaction.SystemException; 32 import javax.transaction.Transaction; 33 import javax.transaction.TransactionManager; 34 import javax.transaction.xa.XAResource; 35 import java.lang.reflect.Method; 36 37 /*** 38 * An XA based Endpoint which uses an XA transaction per message delivery. 39 * 40 * @version $Revision: 1.1.1.1 $ 41 */ 42 public class XAEndpoint implements MessageEndpoint, MessageListener { 43 private static final Log log = LogFactory.getLog(XAEndpoint.class); 44 45 private MessageListener messageListener; 46 private XAResource xaResource; 47 private TransactionManager transactionManager; 48 private Transaction transaction; 49 private boolean beforeDeliveryCompleted; 50 private boolean messageDelivered; 51 52 public XAEndpoint(MessageListener messageListener, XAResource xaResource, TransactionManager transactionManager) { 53 this.messageListener = messageListener; 54 this.xaResource = xaResource; 55 this.transactionManager = transactionManager; 56 } 57 58 public void beforeDelivery(Method method) throws NoSuchMethodException, ResourceException { 59 if (transaction != null) { 60 throw new IllegalStateException("Transaction still in progress"); 61 } 62 beforeDeliveryCompleted = false; 63 try { 64 transactionManager.begin(); 65 transaction = transactionManager.getTransaction(); 66 67 transaction.enlistResource(xaResource); 68 beforeDeliveryCompleted = true; 69 70 log.trace("Transaction started and resource enlisted"); 71 } 72 catch (NotSupportedException e) { 73 System.out.println("Caught: " + e); 74 throw new ResourceException(e); 75 } 76 catch (SystemException e) { 77 System.out.println("Caught: " + e); 78 throw new ResourceException(e); 79 } 80 catch (RollbackException e) { 81 System.out.println("Caught: " + e); 82 throw new ResourceException(e); 83 } 84 catch (Throwable e) { 85 System.out.println("Caught: " + e); 86 e.printStackTrace(); 87 throw new ResourceException(e); 88 } 89 } 90 91 public void afterDelivery() throws ResourceException { 92 if (transaction == null) { 93 throw new IllegalStateException("Transaction not in progress"); 94 } 95 if (beforeDeliveryCompleted && messageDelivered) { 96 try { 97 transaction.delistResource(xaResource, XAResource.TMSUSPEND); 98 } 99 catch (SystemException e) { 100 throw new ResourceException(e); 101 } 102 try { 103 transaction.commit(); 104 log.trace("Transaction committed"); 105 } 106 catch (RollbackException e) { 107 throw new ResourceException(e); 108 } 109 catch (HeuristicMixedException e) { 110 doRollback(e); 111 } 112 catch (HeuristicRollbackException e) { 113 doRollback(e); 114 } 115 catch (SystemException e) { 116 doRollback(e); 117 } 118 finally { 119 transaction = null; 120 } 121 } 122 } 123 124 public void onMessage(Message message) { 125 messageDelivered = false; 126 messageListener.onMessage(message); 127 messageDelivered = true; 128 } 129 130 public void release() { 131 if (transaction != null) { 132 try { 133 transaction.rollback(); 134 } 135 catch (SystemException e) { 136 log.warn("Failed to rollback transaction: " + e, e); 137 } 138 } 139 } 140 141 protected void doRollback(Exception e) throws ResourceException { 142 try { 143 transaction.rollback(); 144 log.trace("Transaction rolled back"); 145 } 146 catch (SystemException e1) { 147 log.warn("Caught exception while rolling back: " + e1, e1); 148 } 149 transaction = null; 150 throw new ResourceException(e); 151 } 152 }