package com.voxeo.moho.presence.sip.impl;
import java.util.ListIterator;
import javax.servlet.sip.SipApplicationSession;
import javax.servlet.sip.SipServlet;
import javax.servlet.sip.SipServletRequest;
import javax.servlet.sip.SipSession;
import javax.servlet.sip.SipSessionsUtil;
import javax.servlet.sip.URI;
import org.apache.log4j.Logger;
import com.voxeo.moho.presence.sip.SipSubscriptionState;
import com.voxeo.moho.sip.SIPSubscribeEvent.SIPSubscriptionContext;
import com.voxeo.moho.spi.ExecutionContext;
public class SIPSubscriptionContextImpl implements SIPSubscriptionContext {
private static final long serialVersionUID = 5166897019787952683L;
private static final Logger LOG = Logger.getLogger(SIPSubscriptionContextImpl.class);
private String _subscriber;
private String _subscribee;
private String _eventName;
private String _notifyBodyType;
private int _expires;
private transient SipSession _dialog;
private transient SipSessionsUtil _sessionUtil;
private transient ExecutionContext _context;
private SipSubscriptionState _state;
private SIPSubscriptionID _id;
private long _updateTime;
private String _appId;
public SIPSubscriptionContextImpl(URI from, URI to, SipServletRequest request) {
_subscriber = Utils.getCleanUri(from).toString();
_subscribee = Utils.getCleanUri(to).toString();
_dialog = request.getSession();
_sessionUtil = (SipSessionsUtil) _dialog.getServletContext().getAttribute(SipServlet.SIP_SESSIONS_UTIL);
_appId = _dialog.getApplicationSession().getId();
EventHeader eventHeader = new EventHeader(request.getHeader("Event"));
_id = new SIPSubscriptionID(_dialog.getId(), eventHeader.getEventId());
_eventName = eventHeader.getEventName();
_notifyBodyType = parseNotifyBodyType(request.getHeaders("Accept"));
updateExpires(request.getExpires());
setState(SipSubscriptionStateImpl.ALLOW);
}
private String parseNotifyBodyType(ListIterator<String> notifyBodies) {
if (SIPConstans.EVENT_NAME_PRESENCE.equals(_eventName)) {
//TODO
return SIPConstans.NOTIFY_BODY_PRESENCE;
// for (; notifyBodies.hasNext();) {
// String bodyType = notifyBodies.next();
// if (bodyType.trim().equals(SIPConstans.NOTIFY_BODY_PRESENCE)) {
// return bodyType;
// }
// }
// throw new IllegalArgumentException("Unsupported notify body type");
}
return notifyBodies.next();
}
@Override
public String getSubscriber() {
return _subscriber;
}
@Override
public String getSubscribee() {
return _subscribee;
}
@Override
public String getEventName() {
return _eventName;
}
@Override
public String getNotifyBodyType() {
return _notifyBodyType;
}
@Override
public int getExpires() {
return _expires;
}
public void setExpires(int expires) {
_expires = expires;
}
public void setUpdateTime(long updateDate) {
_updateTime = updateDate;
}
public void updateExpires(int expires) {
setExpires(expires);
setUpdateTime(System.currentTimeMillis());
}
public int getSpareTime() {
long temp = _updateTime + _expires * 1000 - System.currentTimeMillis();
temp = temp / 1000;
return (int) ((temp > 0) ? temp : 0);
}
@Override
public Runnable sendNotify() {
return new NotifyRequest(this);
}
public SipSubscriptionState getState() {
return _state;
}
public void setState(SipSubscriptionState state) {
_state = state;
}
/**
* there two situations the session could be null<br>
* 1. after the sipoint server abnormally restart, all sessions have been
* automatically expired <br>
* 2. in a cluster enviroment, the seesion has not been duplicated fron other server.
*/
public SipSession getDialog() {
try {
if (_dialog == null && _id.getSessionId() != null && _appId != null) {
if (_sessionUtil == null) {
_sessionUtil = (SipSessionsUtil) _context.getServletContext().getAttribute(SipServlet.SIP_SESSIONS_UTIL);
}
SipApplicationSession sas = (SipApplicationSession) _sessionUtil.getApplicationSessionById(_appId);
_dialog = sas.getSipSession(_id.getSessionId());
}
return _dialog;
}
catch (NullPointerException e) {
if (LOG.isTraceEnabled()) {
LOG.trace("", e);
}
// LOG.warn("Invalid subscribe session [" + getAppId() + "," + getSessionId() + "]. " + e);
return null;
}
catch (IllegalStateException e) {
if (LOG.isTraceEnabled()) {
LOG.trace("Not running in container ", e);
}
// LOG.warn("Invalid subscribe session [" + getAppId() + "," + getSessionId() + "]. " + e);
return null;
}
}
@Override
public Object getId() {
return _id;
}
@Override
public String toString() {
return "SIPSubscriptionContext [_subscriber=" + _subscriber + ", _subscribee=" + _subscribee + ", _eventName="
+ _eventName + ", _notifyBodyType=" + _notifyBodyType + ", _expires=" + _expires + ", _state=" + _state + "]";
}
@Override
public void setExecutionContext(ExecutionContext context) {
_context = context;
}
}