package org.mobicents.javax.media.mscontrol; import jain.protocol.ip.mgcp.message.parms.ConnectionIdentifier; import java.io.Serializable; import java.net.URI; import java.rmi.server.UID; import java.util.ArrayList; import java.util.List; import java.util.concurrent.CopyOnWriteArrayList; import javax.media.mscontrol.MediaSession; import javax.media.mscontrol.MsControlException; import javax.media.mscontrol.join.JoinEvent; import javax.media.mscontrol.join.JoinEventListener; import javax.media.mscontrol.join.Joinable; import javax.media.mscontrol.join.JoinableContainer; import javax.media.mscontrol.join.JoinableStream; import javax.media.mscontrol.join.JoinableStream.StreamType; import org.mobicents.jsr309.mgcp.MgcpWrapper; /** * * @author amit bhayani * */ public abstract class AbstractJoinableContainer implements JoinableContainer { protected final String id = (new UID()).toString(); protected MediaSessionImpl mediaSession = null; protected CopyOnWriteArrayList<JoinEventListener> jointEventListenerList = new CopyOnWriteArrayList<JoinEventListener>(); protected AudioJoinableStream audioJoinableStream = null; protected String endpoint = null; protected MgcpWrapper mgcpWrapper; protected volatile MediaObjectState state = null; protected int maxJoinees = 1; public AbstractJoinableContainer() { this.state = MediaObjectState.IDLE; } protected String getId() { return this.id; } public JoinableStream getJoinableStream(StreamType value) throws MsControlException { checkState(); if (value.equals(StreamType.audio)) { return audioJoinableStream; } return null; } public JoinableStream[] getJoinableStreams() throws MsControlException { checkState(); if (audioJoinableStream != null) { return new JoinableStream[] { audioJoinableStream }; } else { return new JoinableStream[] {}; } } public Joinable[] getJoinees() throws MsControlException { checkState(); Joinable[] j = null; if (this.audioJoinableStream != null) { j = new Joinable[this.audioJoinableStream.audJoinStrVsDirMap.size()]; int count = 0; for (AudioJoinableStream ajs : this.audioJoinableStream.audJoinStrVsDirMap.keySet()) { j[count] = ajs.getContainer(); count++; } } else { j = new Joinable[] {}; } return j; } public Joinable[] getJoinees(Direction direction) throws MsControlException { checkState(); if (this.audioJoinableStream == null) { return new Joinable[] {}; } List<JoinableContainer> absJoiCon = new ArrayList<JoinableContainer>(); for (AudioJoinableStream key : this.audioJoinableStream.audJoinStrVsDirMap.keySet()) { Direction d = this.audioJoinableStream.audJoinStrVsDirMap.get(key); if (d.equals(direction) || d.equals(Direction.DUPLEX)) { absJoiCon.add(key.getContainer()); } } Joinable[] j = new Joinable[absJoiCon.size()]; int count = 0; for (JoinableContainer a : absJoiCon) { j[count] = a; count++; } return j; } public void join(Direction direction, Joinable other) throws MsControlException { throw new MsControlException("Not supported yet. Use joinInitiate()"); } public void joinInitiate(Direction direction, Joinable other, Serializable context) throws MsControlException { checkState(); AbstractJoinableContainer absJoiConOther = (AbstractJoinableContainer) other; absJoiConOther.checkState(); if (other.equals(this)) { throw new MsControlException("Container " + this.getURI() + " cannot join to itself"); } if (this.audioJoinableStream == null) { this.audioJoinableStream = new AudioJoinableStream(this); } if (absJoiConOther.audioJoinableStream == null) { absJoiConOther.audioJoinableStream = new AudioJoinableStream(absJoiConOther); } this.audioJoinableStream.joinInitiate(direction, absJoiConOther.audioJoinableStream, context); } public void unjoin(Joinable other) throws MsControlException { throw new MsControlException("Not supported yet. Use unjoinInitiate()"); } public void unjoinInitiate(Joinable other, Serializable context) throws MsControlException { if (!this.state.equals(MediaObjectState.RELEASED)) { AbstractJoinableContainer absJoiConOther = (AbstractJoinableContainer) other; if (!absJoiConOther.state.equals(MediaObjectState.RELEASED)) { if (this.audioJoinableStream == null) { throw new MsControlException("No stream present with this container" + this.getURI() + " for unjoin"); } if (absJoiConOther.audioJoinableStream == null) { throw new MsControlException("No stream present with other container " + absJoiConOther.getURI() + "for unjoin"); } this.audioJoinableStream.unjoinInitiate(absJoiConOther.audioJoinableStream, context); } } } public void addListener(JoinEventListener listener) { jointEventListenerList.add(listener); } public MediaSession getMediaSession() { return this.mediaSession; } public void removeListener(JoinEventListener listener) { jointEventListenerList.remove(listener); } public CopyOnWriteArrayList<JoinEventListener> getStatusEventListenerList() { return this.jointEventListenerList; } private void update(JoinEvent anEvent) { for (JoinEventListener s : this.jointEventListenerList) { s.onEvent(anEvent); } } protected void updateJoined(JoinEvent anEvent, ConnectionIdentifier thisConnId, ConnectionIdentifier otherConnId, AbstractJoinableContainer otheContainer, boolean error) { if (!error) { this.state = MediaObjectState.JOINED; otheContainer.state = MediaObjectState.JOINED; joined(thisConnId, otherConnId); otheContainer.joined(otherConnId, thisConnId); } update(anEvent); } protected void updateUnjoined(JoinEvent anEvent, ConnectionIdentifier thisConnId, ConnectionIdentifier otherConnId, AbstractJoinableContainer otheContainer, boolean error) { if (!error) { if (this.audioJoinableStream.audJoinStrVsDirMap.size() == 0) { if (!(this.state.equals(MediaObjectState.RELEASED))) { this.state = MediaObjectState.IDLE; } resetContainer(); } if (otheContainer.audioJoinableStream.audJoinStrVsDirMap.size() == 0) { if (!(otheContainer.state.equals(MediaObjectState.RELEASED))) { otheContainer.state = MediaObjectState.IDLE; } otheContainer.resetContainer(); } unjoined(thisConnId, otherConnId); otheContainer.unjoined(otherConnId, thisConnId); } update(anEvent); } protected ConnectionIdentifier getConnectionIdentifier(AudioJoinableStream audioJoiStreamOther) { ConnectionIdentifier connId = null; if (this.audioJoinableStream != null) { connId = this.audioJoinableStream.getConnectionIdentifier(audioJoiStreamOther); } return connId; } protected abstract void joined(ConnectionIdentifier thisConnId, ConnectionIdentifier otherConnId); protected abstract void unjoined(ConnectionIdentifier thisConnId, ConnectionIdentifier otherConnId); protected abstract void checkState(); protected abstract MediaObjectState getState(); protected abstract void resetContainer(); protected abstract URI getURI(); @Override public String toString() { return (this.getURI() + " Endpoint = " + this.endpoint); } }