blob: cd627d2d0e118f4165237960a4975782c4837f91 [file] [log] [blame]
/**
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.aries.ejb.openejb.extender;
import java.util.concurrent.atomic.AtomicReference;
import javax.transaction.HeuristicMixedException;
import javax.transaction.HeuristicRollbackException;
import javax.transaction.InvalidTransactionException;
import javax.transaction.NotSupportedException;
import javax.transaction.RollbackException;
import javax.transaction.Synchronization;
import javax.transaction.SystemException;
import javax.transaction.Transaction;
import javax.transaction.TransactionManager;
import javax.transaction.TransactionSynchronizationRegistry;
import org.apache.aries.util.tracker.SingleServiceTracker;
import org.apache.aries.util.tracker.SingleServiceTracker.SingleServiceListener;
import org.osgi.framework.BundleContext;
public class OSGiTransactionManager implements TransactionManager,
TransactionSynchronizationRegistry, SingleServiceListener {
private static class NoTransactionManagerException extends SystemException {
public NoTransactionManagerException() {
super("No Transaction Manager is available");
}
}
private static class NoTransactionSynchronizationRegistryException extends RuntimeException {
public NoTransactionSynchronizationRegistryException() {
super("No Transaction Synchronization Registry is available");
}
}
private final SingleServiceTracker<TransactionManager> tmTracker;
private final SingleServiceTracker<TransactionSynchronizationRegistry> tsrTracker;
private final AtomicReference<TransactionManager> tm =
new AtomicReference<TransactionManager>();
private final AtomicReference<TransactionSynchronizationRegistry> tsr =
new AtomicReference<TransactionSynchronizationRegistry>();
private static final AtomicReference<OSGiTransactionManager> INSTANCE =
new AtomicReference<OSGiTransactionManager>();
private OSGiTransactionManager(BundleContext ctx) {
tmTracker = new SingleServiceTracker<TransactionManager>(ctx, TransactionManager.class, this);
tsrTracker = new SingleServiceTracker<TransactionSynchronizationRegistry>(ctx,
TransactionSynchronizationRegistry.class, this);
tmTracker.open();
tsrTracker.open();
}
private final TransactionManager getTM() throws SystemException {
TransactionManager tManager = tm.get();
if(tManager == null) {
throw new NoTransactionManagerException();
}
return tManager;
}
private final TransactionSynchronizationRegistry getTSR() {
TransactionSynchronizationRegistry tSReg = tsr.get();
if(tSReg == null) {
throw new NoTransactionSynchronizationRegistryException();
}
return tSReg;
}
public static OSGiTransactionManager get() {
return INSTANCE.get();
}
public static void init(BundleContext ctx) {
OSGiTransactionManager oTM = new OSGiTransactionManager(ctx);
if(!!!INSTANCE.compareAndSet(null, oTM))
oTM.destroy();
}
public void destroy() {
INSTANCE.set(null);
tmTracker.close();
tsrTracker.close();
}
public void serviceFound() {
update();
}
public void serviceLost() {
update();
}
public void serviceReplaced() {
update();
}
private void update() {
tm.set(tmTracker.getService());
tsr.set(tsrTracker.getService());
}
public void begin() throws NotSupportedException, SystemException {
getTM().begin();
}
public void commit() throws HeuristicMixedException,
HeuristicRollbackException, IllegalStateException, RollbackException,
SecurityException, SystemException {
getTM().commit();
}
public int getStatus() throws SystemException {
return getTM().getStatus();
}
public Transaction getTransaction() throws SystemException {
return getTM().getTransaction();
}
public void resume(Transaction arg0) throws IllegalStateException,
InvalidTransactionException, SystemException {
getTM().resume(arg0);
}
public void rollback() throws IllegalStateException, SecurityException,
SystemException {
getTM().rollback();
}
public void setRollbackOnly() throws IllegalStateException {
getTSR().setRollbackOnly();
}
public void setTransactionTimeout(int arg0) throws SystemException {
getTM().setTransactionTimeout(arg0);
}
public Transaction suspend() throws SystemException {
return getTM().suspend();
}
public Object getResource(Object arg0) {
return getTSR().getResource(arg0);
}
public boolean getRollbackOnly() {
return getTSR().getRollbackOnly();
}
public Object getTransactionKey() {
return getTSR().getTransactionKey();
}
public int getTransactionStatus() {
return getTSR().getTransactionStatus();
}
public void putResource(Object arg0, Object arg1) {
getTSR().putResource(arg0, arg1);
}
public void registerInterposedSynchronization(Synchronization arg0) {
getTSR().registerInterposedSynchronization(arg0);
}
}