private void invokeCreatedOrFetchedServerTransaction(
SipServletRequestImpl req, String branchId) {
boolean isTransactionCreated = false;
ServerTransaction st = null;
ServerTransaction stCancel = null;
SipServletResponseImpl resp = null;
String branchIdCancel=null;
Object newMutex = new Object();
Object mutex=null;
if (req.getMethod().equals("CANCEL")) {
// to distinguish cancel from original transaction add method to branch id...
branchIdCancel=branchId + req.getMethod();
mutex = stLockMap.putIfAbsent(branchIdCancel, newMutex);
} else {
mutex = stLockMap.putIfAbsent(branchId, newMutex);
}
if (mutex == null) {
mutex = newMutex;
}
synchronized (mutex) {
st = stMap.get(branchId);
if (req.getMethod().equals("CANCEL")) {
stCancel = stMap.get(branchIdCancel);
if (st != null) {
if (stCancel == null || !NonInviteServerTransaction.class.isInstance(stCancel)) {
stCancel = new NonInviteServerTransaction(branchIdCancel, req);
putServerTransaction(stCancel);
req.pushTransactionDispatcher(stCancel);
req.pushApplicationDispatcher(this);
isTransactionCreated = true;
}
} else if (stCancel == null) {
// orginal transaction to cancel is gone...
resp = req.createTerminatingResponse(481);
resp.setRemote(req.getRemote());
}
} else if (st == null) {
st = req.getMethod().equals("INVITE")
? new InviteServerTransaction(branchId, req)
: new NonInviteServerTransaction(branchId, req);
req.pushTransactionDispatcher(st); // Push the new ST
req.pushApplicationDispatcher(this);
putServerTransaction(st);
isTransactionCreated = true;
}
}
// invoke outside synchronization block...
if (resp != null) {
// orginal transaction to cancel is gone, lets reply...
resp.popDispatcher().dispatch(resp);
} else if (stCancel != null) {
// lets inform the original transaction
// that a cancel request is pending...
if (isTransactionCreated) {
st.handleCancel(stCancel);