Package com.ericsson.ssa.sip

Source Code of com.ericsson.ssa.sip.SipSessionDialogImpl$AttributeCallback

/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright 1997-2009 Sun Microsystems, Inc. All rights reserved.
* Copyright (c) Ericsson AB, 2004-2008. All rights reserved.
*
* The contents of this file are subject to the terms of either the GNU
* General Public License Version 2 only ("GPL") or the Common Development
* and Distribution License("CDDL") (collectively, the "License").  You
* may not use this file except in compliance with the License. You can obtain
* a copy of the License at https://glassfish.dev.java.net/public/CDDL+GPL.html
* or glassfish/bootstrap/legal/LICENSE.txt.  See the License for the specific
* language governing permissions and limitations under the License.
*
* When distributing the software, include this License Header Notice in each
* file and include the License file at glassfish/bootstrap/legal/LICENSE.txt.
* Sun designates this particular file as subject to the "Classpath" exception
* as provided by Sun in the GPL Version 2 section of the License file that
* accompanied this code.  If applicable, add the following below the License
* Header, with the fields enclosed by brackets [] replaced by your own
* identifying information: "Portions Copyrighted [year]
* [name of copyright owner]"
*
* Contributor(s):
*
* If you wish your version of this file to be governed by only the CDDL or
* only the GPL Version 2, indicate your decision by adding "[Contributor]
* elects to include this software in this distribution under the [CDDL or GPL
* Version 2] license."  If you don't indicate a single choice of license, a
* recipient has the option to distribute your version of this file under
* either the CDDL, the GPL Version 2 or to extend the choice of license to
* its licensees as provided above.  However, if you add GPL Version 2 code
* and therefore, elected the GPL Version 2 license, then the option applies
* only if the new code is made subject to such option by the copyright
* holder.
*/
package com.ericsson.ssa.sip;

import org.jvnet.glassfish.comms.deployment.backend.SipApplicationListeners;
import com.ericsson.ssa.sip.PathNode.Type;
import com.ericsson.ssa.sip.dialog.DialogCleaner;

import org.apache.catalina.Globals;

import org.jvnet.glassfish.comms.util.LogUtil;

import java.io.IOException;
import java.io.ObjectInput;
import java.io.ObjectOutput;
import java.io.Externalizable;

import java.security.AccessController;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.Map.Entry;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.logging.Level;
import java.util.logging.Logger;

import javax.servlet.ServletContext;
import javax.servlet.sip.Address;
import javax.servlet.sip.SipSession;
import javax.servlet.sip.SipSessionActivationListener;
import javax.servlet.sip.SipSessionAttributeListener;
import javax.servlet.sip.SipSessionBindingEvent;
import javax.servlet.sip.SipSessionBindingListener;
import javax.servlet.sip.SipSessionEvent;
import javax.servlet.sip.SipSessionListener;
import javax.servlet.sip.URI;
import javax.servlet.sip.ar.SipApplicationRoutingRegion;

public class SipSessionDialogImpl extends SipSessionImplBase
    implements LifeCycle {
    private static Logger logger = LogUtil.SIP_LOGGER.getLogger();
    private static final long serialVersionUID = 3762535598732096310L;
    private static final String SS_DESCRIPTION = "SipSession with id ";

    /** The serialized format versioning. 1 = first version. */
    private static final short serializedFormVersion  = 1;

    private transient ArrayList<SipSessionListener> sessionListeners = null;
    private Map<String, Object> sessionAttributeMap;
    protected SipApplicationSessionImpl sipApplicationSession = null;
    protected SipSessionManager sipSessionManager = null;
    protected String sasId = null;
    private String handler = null;
    private Type type = null;
    protected String id; // final
    private Address to; // Final
    private long creationDate = new Date().getTime(); // Final
    private long lastAccessedTime;
    private long currentAccessedTime;
    private long expirationTime;
    private String dialogFragmentId; // Final
    private boolean isDerived = false;
    private AtomicInteger cSeq = null;
    private URI remoteTarget = null;
    private boolean is1xxReliableOngoing = false;
    private boolean is1xxReliableSDP = false;
    private boolean updateOngoing = false;
    private State sessionState = State.INITIAL;
    private transient boolean shouldBePersisted = false;

    // JSR289
    private SipApplicationRoutingRegion routingRegion = null;
    private URI subscriberURI = null;
    private String linkedSipSessionId = null;
   
    private String correspondingJoin = null;
    private String correspondingReplaces = null;
   
    /**
     * This boolean controls the values that getLocalParty() and
     * getRemoteParty() should return. It is false by default, which provides
     * the correct behaviour for UAC and proxy SipSessions. When an application
     * has decided to take the UAS role this attribute is set to true for the
     * SipSession, causing getLocalParty() and getRemoteParty() to respond
     * differently.
     */
    private boolean swapLocalRemote = false;

    public SipSessionDialogImpl(SipSessionManagerBase manager, DialogSet set,
            Address to, SipApplicationSessionImpl appSession, String handler,
            Type type) {
        super(set);
        init(manager, to, appSession, handler, type);
        initListeners(sipApplicationSession.getSipApplicationListeners());
        initInvalidateWhenReady();
    }

    protected void init(SipSessionManagerBase manager,
            Address to, SipApplicationSessionImpl appSession, String handler,
            Type type) {
        sipSessionManager = manager;
        // remove to-tag
        this.to = (Address) ((AddressImpl) to).clone(false, false);
        ((AddressImpl) this.to).setReadOnly(true);
        sipApplicationSession = appSession;
        sasId = appSession.getId();
        this.handler = handler;
        this.type = type;

        // if user agent then a cseq counter is needed, otherwise save memory...
        if (type.equals(Type.Caller) || type.equals(Type.Callee)) {
            createPFieldCSeq();
        }

        // important that id exist before adding to app session...
        id = createID().toString();
        sipApplicationSession.addSession(this);

        currentAccessedTime = System.currentTimeMillis();
        lastAccessedTime = currentAccessedTime;
    }

    /**
     * For serialization only.
     */
    public SipSessionDialogImpl() {
        super(null);
    }


    /**
     * Gets the id to be included in the serialized representation of this
     * SipSession. Normally, this will be the same as the id of
     * this SipSession, but subclasses may override this method to
     * return null or an empty string (for optimization purposes), if they
     * are able to obtain the id from another source after deserialization.
     */
    protected String getIdForSerial() {
        return id;
    }


    /**
     * Notifies any interested session attributes that this session has been
     * activated.
     */
    public void notifySessionDidActivate() {
        Iterator attrValues = getSessionAttributeMap(false).values().iterator();
        SipSessionEvent sipSessionEvent = new SipSessionEvent(this);
        while (attrValues.hasNext()) {
            Object attrValue = attrValues.next();

            if (attrValue instanceof SipSessionActivationListener) {
                ((SipSessionActivationListener) attrValue).sessionDidActivate(sipSessionEvent);
            }
        }
    }

    /**
     * Notifies any interested session attributes that this session is about
     * to be passivated.
     */
    public void notifySessionWillPassivate() {
        Iterator attrValues = getSessionAttributeMap(false).values().iterator();
        SipSessionEvent sipSessionEvent = new SipSessionEvent(this);
        while (attrValues.hasNext()) {
            Object attrValue = attrValues.next();

            if (attrValue instanceof SipSessionActivationListener) {
                ((SipSessionActivationListener) attrValue).sessionWillPassivate(sipSessionEvent);
            }
        }
    }
   

    public void doCleanup() {
        sipSessionManager.removeSipSession(this);
        if (logger.isLoggable(Level.FINEST)) {
            logger.log(Level.FINEST, "The sip session with ID="+getId()+" has been removed from the active cache.");
        }
        SipApplicationSessionImpl sas = (SipApplicationSessionImpl) getApplicationSessionLocally();
        if (sas != null && !sas.isValid() && !sas.isForegroundLocked()) {
            sas.doCleanup();
        } else if (sas != null && !sas.isValid()) {
            // The SAS is still FG locked give it another 32 seconds, then remove it regardless of lock state.
            DialogCleaner.getInstance().registerForSupervision(sas, 32000);
        }

    }

    protected final void notifySessionCreated() {
        ArrayList<SipSessionListener> someSessionListeners = getSipSessionListeners();

        if (someSessionListeners == null) {
            return;
        }
        SipSessionEvent sipSessionEvent = new SipSessionEvent(this);
        for (Iterator<SipSessionListener> lIter = someSessionListeners.iterator();
                lIter.hasNext();) {
            SipSessionListener listener = lIter.next();
            listener.sessionCreated(sipSessionEvent);
        }
    }

    protected final void notifySessionDestroyed() {
        ArrayList<SipSessionListener> someSessionListeners = getSipSessionListeners();

        if (someSessionListeners == null) {
            return;
        }
        SipSessionEvent sipSessionEvent = new SipSessionEvent(this);
        for (Iterator<SipSessionListener> lIter = someSessionListeners.iterator();
                lIter.hasNext();) {
            SipSessionListener listener = lIter.next();
            listener.sessionDestroyed(sipSessionEvent);
        }
    }

    protected final void initListeners(SipApplicationListeners appListeners) {
        if (appListeners != null) {
            setSipSessionListeners(appListeners.getSipSessionListeners());
        }

        notifySessionCreated();
    }

    protected void setSipSessionListeners(
        ArrayList<SipSessionListener> sipSessionListeners) {
        this.sessionListeners = sipSessionListeners;
    }

    @Override
    protected synchronized ArrayList<SipSessionListener> getSipSessionListeners() {
        if (sessionListeners == null) {
            SipSessionManager ssm = getPFieldSipSessionManagerField();
            if (ssm != null) {
                sessionListeners = ssm.getContext()
                        .getSipApplicationListeners()
                        .getSipSessionListeners();
            }

            if (sessionListeners == null) {
                logger.log(Level.WARNING, "SipSessionListener list not found");
            }
        }

        return sessionListeners;
    }

    public int getCSeq() {
        return getPFieldCSeq();
    }

    @Override
    protected Object getFromPFieldSessionAttribute(String name) {
        return getSessionAttributeMap(false).get(name);
    }

    @Override
    protected void addToPFieldSessionAttribute(String name, Object value) {
        Object oldValue = getSessionAttributeMap(true).put(name, value);
        if(oldValue==null){
          // No old value => the attribute was added
          attributeAdded(name,value);
        }
        else {
          // An old value
          if(oldValue!=value){
            // Call replaced only if it is a different value.
            attributeReplaced(name,oldValue,value);
          }
        }
    }

    @Override
    protected Collection<String> getFromPFieldSessionAttributeNames() {
        return getSessionAttributeMap(false).keySet();
    }

    @Override
  protected void removeFromPFieldSessionAttribute(String name) {
    Object removedAttribute = getSessionAttributeMap(false).remove(name);
    if (removedAttribute != null) {
      // Call attributeRemoved on listeners ONLY if an attribute actually
      // has been removed
      attributeRemoved(name, removedAttribute);
    }
  }

    /**
   * Helper interface for invocation of a callback on a listener.
   *
   * This interface is used to be able to write the
   * <code>callAttributeListeners</code> method without duplicating that
   * code and hence have a maintenance problem.
   *
   * An alternative to this approach is to use a switch case on an enum or to
   * use reflection. I like this approach best since it is the most object
   * oriented and type safe approach.
   *
   * @author Magnus Hessel, HiQ Stockholm AB
   *
   */
   private static interface AttributeCallback {
    void call(SipSessionBindingEvent event,
        SipSessionAttributeListener listener);
    static final AttributeCallback ADDED = new AttributeCallback() {
      public void call(SipSessionBindingEvent event,
          SipSessionAttributeListener listener) {
        listener.attributeAdded(event);
      }
    };

     static final AttributeCallback REPLACED = new AttributeCallback() {
      public void call(SipSessionBindingEvent event,
          SipSessionAttributeListener listener) {
        listener.attributeReplaced(event);
      }
    };

     static final AttributeCallback REMOVED = new AttributeCallback() {
      public void call(SipSessionBindingEvent event,
          SipSessionAttributeListener listener) {
        listener.attributeRemoved(event);
      }
    };
  }


   /**
    * Helper to call a callback on all SipSessionAttributeListeners.
    *
    * @param callback Which callback to invoke
    * @param attributeName Name of attribute the callback involves
    */
  private void callAttributeListeners(AttributeCallback callback, String attributeName) {
    // List all listeners
    List<SipSessionAttributeListener> sipSessionAttributeListeners = getApplicationSessionImpl()
        .getSipApplicationListeners().getSipSessionAttributeListeners();
    // If there are at least one, create event and call all of them.
    if (sipSessionAttributeListeners != null
        && !sipSessionAttributeListeners.isEmpty()) {
      SipSessionBindingEvent event = new SipSessionBindingEvent(this,
          attributeName);
      for (SipSessionAttributeListener listener : sipSessionAttributeListeners) {
        callback.call(event, listener);
      }
    }
  }


  /**
   * Called when an attribute is added
   *
   * @param name
   */
  private void attributeAdded(String name,Object addedObject) {
    callAttributeListeners(AttributeCallback.ADDED, name);
    if(addedObject instanceof SipSessionBindingListener){
      ((SipSessionBindingListener)addedObject).valueBound(new SipSessionBindingEvent(this,name));
    }
  }

  /**
   * Called when an attribute is replaced
   *
   * @param name
   */
  private void attributeReplaced(String name,Object oldValue,Object newValue) {
    callAttributeListeners(AttributeCallback.REPLACED, name);
    if(oldValue instanceof SipSessionBindingListener){
      ((SipSessionBindingListener)oldValue).valueUnbound(new SipSessionBindingEvent(this,name));
    }
    if(newValue instanceof SipSessionBindingListener){
      ((SipSessionBindingListener)newValue).valueBound(new SipSessionBindingEvent(this,name));
    }
  }

  /**
   * Called when an attribute is removed
   *
   * @param name
   */
  private void attributeRemoved(String name, Object removedValue) {
    callAttributeListeners(AttributeCallback.REMOVED, name);
    if(removedValue instanceof SipSessionBindingListener){
      ((SipSessionBindingListener)removedValue).valueUnbound(new SipSessionBindingEvent(this,name));
    }
  }


  /**
   * Notify all SipSessionBindingListeners that are values that this
   * the binding to this SipSession is due.
   */
    @Override
  protected void notifyAttributesUnbound() {
      if(sessionAttributeMap!=null){
      Set<Entry<String, Object>> entries = sessionAttributeMap.entrySet();
      for(Entry<String, Object> entry : entries){
        Object value = entry.getValue();
        if(value instanceof SipSessionBindingListener){
          ((SipSessionBindingListener)value).valueUnbound(new SipSessionBindingEvent(this,entry.getKey()));
        }
      }
      }
  }
 
  private Map<String, Object> getSessionAttributeMap(boolean create) {
        if (sessionAttributeMap == null) {
            if (create) {
                sessionAttributeMap = new HashMap<String, Object>(8);
            } else {
                return Collections.emptyMap();
            }
        }

        return sessionAttributeMap;
    }

    @Override
    protected boolean getPField1xxReliableOngoing() {
        return is1xxReliableOngoing;
    }

    @Override
    protected boolean getPField1xxReliableSDP() {
        return is1xxReliableSDP;
    }

    @Override
    protected int incrementAndGetPFieldCSeq() {
        return cSeq.incrementAndGet();
    }

    @Override
    protected boolean hasPFieldCSeq() {
        return cSeq != null;
    }

    @Override
    protected void createPFieldCSeq() {
        cSeq = new AtomicInteger(SipFactoryImpl.START_CSEQ);
    }

    // also give subclasses access cseq
    protected void setPFieldCSeq(int aCseq) {
        cSeq = new AtomicInteger(aCseq);
    }

    public int getPFieldCSeq() {
        if (cSeq == null) {
            return -1;
        }

        return cSeq.get();
    }

    @Override
    protected long getPFieldCreationDate() {
        return creationDate;
    }

    @Override
    protected boolean getPFieldDerived() {
        return isDerived;
    }

    @Override
    public String getPFieldDialogFragmentId() {
        return dialogFragmentId;
    }

    @Override
    protected String getPFieldHandler() {
        return handler;
    }

    @Override
    protected String getPFieldId() {
        return id;
    }

    @Override
    protected long getPFieldLastAccessedTime() {
        return lastAccessedTime;
    }

    @Override
    protected long getPFieldCurrentAccessedTime() {
        return currentAccessedTime;
    }

    @Override
    protected String getPFieldLinkedSipSessionId() {
        return linkedSipSessionId;
    }
   
    @Override
    protected String getPFieldCorrespondingSipSessionId(String header) {
        if (header.equals(Header.JOIN)) {
            return correspondingJoin;
        } else {
            return correspondingReplaces;
        }
    }

    @Override
    protected SipApplicationRoutingRegion getPFieldRoutingRegion() {
        return routingRegion;
    }

    @Override
    protected URI getPFieldRemoteTarget() {
        return remoteTarget;
    }

    @Override
    protected synchronized SipApplicationSessionImpl getPFieldSipApplicationSession() {
        if (sipApplicationSession == null) {
            try {
                SipSessionManager ssm = getPFieldSipSessionManagerField();               
                if(ssm != null) {
                    sipApplicationSession = (SipApplicationSessionImpl) ssm.findSipApplicationSession(sasId);
                }
            } catch (RemoteLockException e) {
                throw new RemoteLockRuntimeException(e);
            }
        }

        return sipApplicationSession;
    }

    /**
     * sipSessionManager will be null after deserializing the SS object
     * back from the ObjectInputStream. So, the deserializer must explicitly
     * set the sipSessionManager after deserialization, which means that the
     * serialization/deserialization of the SS object should only be done in a
     * context using the appropriate SipStore interfaces.
     *
     * @return the sip session manager.
     */
    @Override
    protected SipSessionManager getPFieldSipSessionManagerField() {
        return sipSessionManager;
    }

    /**
     * The sipSessionManager must be explicitly set by the deserializer after
     * deserializing the SS object back from the ObjectInputStream.
     *
     * @see org.jvnet.glassfish.comms.replication.sessmgmt.SipSessionStoreImpl
     *
     * @param manager sip session mananger.
     */
    public void setSipSessionManager(SipSessionManager manager) {
        this.sipSessionManager = manager;
    }
   
    @Override
    protected State getPFieldSessionState() {
        return sessionState;
    }

    @Override
    protected URI getPFieldSubscriberURI() {
        return subscriberURI;
    }

    @Override
    protected boolean getPFieldSwapLocalRemote() {
        return swapLocalRemote;
    }

    @Override
    protected Address getPFieldTo() {
        return to;
    }

    @Override
    protected Type getPFieldType() {
        return type;
    }

    @Override
    protected boolean getPFieldUpdateOngoing() {
        return updateOngoing;
    }

    @Override
    protected void setPField1xxReliableOngoing(boolean is1xxReliableOngoing) {
        this.is1xxReliableOngoing = is1xxReliableOngoing;
    }

    @Override
    protected void setPField1xxReliableSDP(boolean is1xxReliableSDP) {
        this.is1xxReliableSDP = is1xxReliableSDP;
    }

    @Override
    protected void setPFieldDerived(boolean isDerived) {
        this.isDerived = isDerived;
    }

    @Override
    protected void setPFieldDialogFragmentId(String dialogFragmentId) {
        this.dialogFragmentId = dialogFragmentId;
    }

    @Override
    protected void setPFieldHandler(String handler) {
        this.handler = handler;
    }

    @Override
    protected void setPFieldLinkedSipSessionId(String linkedSipSessionId) {
        this.linkedSipSessionId = linkedSipSessionId;
    }
   
    @Override
    protected void setPFieldCorrespondingSipSessionId(String id, String header) {
        if (header.equals(Header.JOIN)) {
            this.correspondingJoin = id;
        } else {
            this.correspondingReplaces = id;
        }
    }
   
    @Override
    protected void setPFieldRemoteTarget(URI remoteContact) {
        this.remoteTarget = remoteContact;
    }

    @Override
    protected void setPFieldRoutingRegion(SipApplicationRoutingRegion routingRegion) {
        this.routingRegion = routingRegion;
    }

    @Override
    protected synchronized void setPFieldSipApplicationSession(
        SipApplicationSessionImpl sipApplicationSession) {
        this.sipApplicationSession = (SipApplicationSessionImpl) sipApplicationSession;
    }

    @Override
    protected void setPFieldSessionState(State state) {
        this.sessionState = state;
    }

    @Override
    protected void setPFieldSubscriberURI(URI subscriberURI) {
        this.subscriberURI = subscriberURI;
    }

    @Override
    protected void setPFieldSwapLocalRemote(boolean swapLocalRemote) {
        this.swapLocalRemote = swapLocalRemote;
    }

    @Override
    protected void setPFieldTo(Address to) {
        this.to = to;
    }

    @Override
    protected void setPFieldType(Type type) {
        this.type = type;
    }

    @Override
    protected void setPFieldUpdateOngoing(boolean updateOngoing) {
        this.updateOngoing = updateOngoing;
    }

    @Override
    protected void setPFieldLastAccessedTime(long lastAccessedTime) {
        this.lastAccessedTime = lastAccessedTime;
    }
   
    @Override
    protected void setPFieldCurrentAccessedTime(long currentAccessedTime) {
        this.currentAccessedTime = currentAccessedTime;
    }

    @Override
    protected long getPFieldExpirationTime() {
        return expirationTime;
    }

    @Override
    protected void setPFieldExpirationTime(long expTime) {
        expirationTime = expTime;
    }

    public void setShouldBePersisted() {
        sipApplicationSession.setSipSessionShouldBePersisted(this);
        shouldBePersisted = true;
    }

    public boolean shouldBePersisted() {
        SipSessionManager manager = getSipSessionManager();
        if (manager != null && manager.isBeingReleased()) {
            return false;
        }

        return shouldBePersisted;
    }

    /**
     * @serialData See serialized form version 1 in #readExternal(ObjectInput in)
     * 
     * @param oos the stream to write the object members
     * @throws IOException
     */
    public void writeExternal(ObjectOutput out) throws IOException {
        out.writeShort(serializedFormVersion);
        super.writeExternal(out);
        // FIXME check that we are in confirmed state, otherwise throw IllegalStateException
        out.writeObject(sasId);

        // Serialize session attributes
        IOUtil.writeSessionAttributes(getSessionAttributeMap(false), out);

        out.writeObject(handler);
        out.writeObject(type);
        out.writeObject(getIdForSerial());
        out.writeObject(to);
        out.writeLong(creationDate);
        out.writeLong(expirationTime); // possibly overridden by extraparams
        out.writeLong(lastAccessedTime);
        out.writeLong(currentAccessedTime);
        out.writeObject(dialogFragmentId);
        out.writeBoolean(isDerived);
        out.writeBoolean(swapLocalRemote);

        if (cSeq != null) {
            out.writeInt(cSeq.get());
        } else {
            out.writeInt(-1); // Indicate null cSeq
        }

        out.writeObject(remoteTarget);

        // JSR289
        out.writeObject(subscriberURI);
        out.writeObject(routingRegion);
        out.writeObject(linkedSipSessionId);
       
        out.writeObject(correspondingJoin);
        out.writeObject(correspondingReplaces);

        out.writeObject(sessionState);
    }

    /**
     * @serialData first field is an short and represents the serializedFormVersion.<br><br>
     * <h3>Data layout for serializedFormVersion = 1 follows</h3>
     *
     * <li>field is a <b>Externalizable</b> and represents superclass externalized data</li>
     * <li>field is a <b>String</b> and represents application id</li>
     * <li>field is a <b>String</b> and represents sip application session id</li>
     * <li>field is a <b>Integer</b> and represents number of key-value attributes serialized</li>
     * <li>0..n key-value fields as <b>Object</b> and represents key-value attributes</li>
     * <li>field is a <b>String</b> and represents the name of the servlet handler</li>
     *
     * <li>field is a <b>Type</b> and represents the Type</li>
     * <li>field is a <b>String</b> and represents session id</li>
     * <li>field is a <b>javax.servlet.sip.Address</b> and represents the to field</li>
     * <li>field is a <b>Long</b> and represents the creation date of session</li>
     * <li>field is a <b>Long</b> and represents the expirationTime field as absolute time</li>
     * <li>field is a <b>Long</b> and represents the lastAccessedTime field as absolute time</li>
     * <li>field is a <b>Long</b> and represents the currentAccessedTime field as absolute time</li>
     * <li>field is a <b>String</b> and represents the dialogFragmentId</li>
     * <li>field is a <b>Boolean</b> and represents the isDerived field</li>
     * <li>field is a <b>Boolean</b> and represents the swapLocalRemote field</li>
     * <li>field is a <b>Integer</b> and represents the cseq field</li>
     * <li>field is a <b>javax.servlet.sip.URI</b> and represents the remote target</li>
     * <li>field is a <b>javax.servlet.sip.URI</b> and represents the suscriber URI</li>
     * <li>field is a <b>String</b> and represents the routing region</li>
     * <li>field is a <b>String</b> and represents the linkedSipSessionId</li>
     * <li>field is a <b>String</b> and represents the corresponding join id.</li>
     * <li>field is a <b>String</b> and represents the corresponding replace id.</li>
     * <li>field is a <b>javax.servlet.sip.SipSession.State</b> and represents the sessionState</li>
     *
     * @param in the stream to read the object members
     * @throws IOException is thrown when unsupported version is detected
     * @throws ClassNotFoundException
     */   
    public void readExternal(ObjectInput in)
        throws IOException, ClassNotFoundException {
        short readSerializedFormVersion = in.readShort();
        switch(readSerializedFormVersion) {
        case 1:
            super.readExternal(in);
            // Read the appid, and use it to get the corresponding
            // SipSessionManager and associated context.
            sasId = (String) in.readObject();
   
            // Deserialize session attributes
            sessionAttributeMap = IOUtil.readSessionAttributes(in);
   
            handler = (String) in.readObject();
            type = (Type) in.readObject();
            id = (String) in.readObject();
            to = (Address) in.readObject();
            creationDate = in.readLong();
            expirationTime = in.readLong();
            lastAccessedTime = in.readLong();
            currentAccessedTime = in.readLong();
            dialogFragmentId = (String) in.readObject();
            isDerived = in.readBoolean();
            swapLocalRemote = in.readBoolean();
   
            int cseqInt = in.readInt();
   
            if (cseqInt > -1) {
                // OK cSeq was not null at writeObject()
                cSeq = new AtomicInteger(cseqInt);
            }
   
            remoteTarget = (URI) in.readObject();
   
            // JSR289
            subscriberURI = (URI) in.readObject();
            routingRegion = (SipApplicationRoutingRegion) in.readObject();
            linkedSipSessionId = (String) in.readObject();
           
            correspondingJoin = (String) in.readObject();
            correspondingReplaces = (String) in.readObject();

            sessionState = (State) in.readObject();
   
            shouldBePersisted = true;
            break;
        default:
            throw new IOException("Unable to deserialize into "
                    + this.getClass().getName()
                    + " with serialVersionUID = " + serialVersionUID
                    + " due to unknown serializedFormVersion of "
                    + readSerializedFormVersion);
        }
    }

    /**
     * Activates this SipSession.
     */
    public boolean activate() {
        // Add to active cache
        SipSessionManager mgr = getSipSessionManager();
        if (mgr != null) {
            SipSession ss = mgr.addSipSession(this);
            if (ss != null) {
                // While this thread has been in the process of loading the
                // requested SipSession, and is now trying to activate it,
                // another thread has also loaded the same SipSession, and
                // has already added it to the active cache. Abort activation.
                return true;
            }
        }

        notifySessionDidActivate();

        return true;
    }

    /**
     * Passivates this SipSession.
     */
    public void passivate() {
        notifySessionWillPassivate();

        // Remove from active cache
        SipSessionManager mgr = getSipSessionManager();
        if (mgr != null) {
            mgr.removeSipSession(this);
        }
    }

    public String toString() {
        return SS_DESCRIPTION + getApplicationId() + ":" + id;
    }

    /**
     * Gets the application session from the local cache only. If it is not found in the local cache null is returned.
     * @return
     */
    public SipApplicationSessionImpl getApplicationSessionLocally() {
        try {
            return sipSessionManager.findSipApplicationSession(sasId);
        } catch (RemoteLockException e) {
            if (logger.isLoggable(Level.WARNING)) {
                logger.log(Level.WARNING, "This can never happen: SipApplicationSession was remotely locked: " + sasId);
            }
            return null;
        }
    }

    /*
     * Returns the application id of this SipSession.
     *
     * @return the application id of this SipSession
     */
    public String getApplicationId() {
        return sipSessionManager != null
                ? sipSessionManager.getApplicationId() : null;
    }
}
TOP

Related Classes of com.ericsson.ssa.sip.SipSessionDialogImpl$AttributeCallback

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.