Implements IQ and IQProvider for the cobri Jabber extension.

cusax-fix
Lyubomir Marinov 15 years ago
parent ba78226fe9
commit 11d8d7f429

@ -15,6 +15,8 @@
import javax.net.ssl.*;
import net.java.sip.communicator.impl.protocol.jabber.debugger.*;
import net.java.sip.communicator.impl.protocol.jabber.extensions.*;
import net.java.sip.communicator.impl.protocol.jabber.extensions.cobri.*;
import net.java.sip.communicator.impl.protocol.jabber.extensions.keepalive.*;
import net.java.sip.communicator.service.protocol.*;
import net.java.sip.communicator.service.protocol.event.*;
@ -209,7 +211,7 @@ public class ProtocolProviderServiceJabberImpl
/**
* Used to connect to a XMPP server.
*/
private XMPPConnection connection = null;
private XMPPConnection connection;
/**
* Indicates whether or not the provider is initialized and ready for use.
@ -449,9 +451,9 @@ public void register(final SecurityAuthority authority)
{
// Checks if an error has occurred during login, if so we fire
// it here in order to avoid a deadlock which occurs in
// reconnect plugin. The deadlock is cause we fired an event during
// login process and have locked initializationLock and we cannot
// unregister from reconnect, cause unregister method
// reconnect plugin. The deadlock is cause we fired an event
// during login process and have locked initializationLock and
// we cannot unregister from reconnect, cause unregister method
// also needs this lock.
if(eventDuringLogin != null)
{
@ -1578,9 +1580,9 @@ protected void initialize(String screenname,
// RTP HDR extension
supportedFeatures.add(URN_XMPP_JINGLE_RTP_HDREXT);
//register our jingle provider
//register our home grown Jingle Provider.
ProviderManager providerManager = ProviderManager.getInstance();
//register our jingle provider
providerManager.addIQProvider( JingleIQ.ELEMENT_NAME,
JingleIQ.NAMESPACE,
new JingleIQProvider());
@ -1606,6 +1608,24 @@ protected void initialize(String screenname,
JingleInfoQueryIQ.NAMESPACE,
new JingleInfoQueryIQProvider());
// Jitsi VideoBridge IQProvider and PacketExtensionProvider
providerManager.addIQProvider(
CobriConferenceIQ.ELEMENT_NAME,
CobriConferenceIQ.NAMESPACE,
new CobriIQProvider());
providerManager.addExtensionProvider(
PayloadTypePacketExtension.ELEMENT_NAME,
CobriConferenceIQ.NAMESPACE,
new DefaultPacketExtensionProvider<
PayloadTypePacketExtension>(
PayloadTypePacketExtension.class));
providerManager.addExtensionProvider(
ParameterPacketExtension.ELEMENT_NAME,
CobriConferenceIQ.NAMESPACE,
new DefaultPacketExtensionProvider<
ParameterPacketExtension>(
ParameterPacketExtension.class));
//initialize the telephony operation set
boolean isCallingDisabled
= JabberActivator.getConfigurationService()
@ -2179,16 +2199,7 @@ public boolean isFeatureSupported(String jid, String feature)
*/
public String getFullJid(Contact contact)
{
XMPPConnection connection = getConnection();
if (connection == null)
return null;
Roster roster = getConnection().getRoster();
if (roster == null)
return null;
return roster.getPresence(contact.getAddress()).getFrom();
return getFullJid(contact.getAddress());
}
/**
@ -2203,13 +2214,15 @@ public String getFullJid(Contact contact)
public String getFullJid(String bareJid)
{
XMPPConnection connection = getConnection();
if (connection == null)
return null;
Roster roster = getConnection().getRoster();
Presence presence = roster.getPresence(bareJid);
if (connection != null)
{
Roster roster = connection.getRoster();
return presence.getFrom();
if (roster != null)
return roster.getPresence(bareJid).getFrom();
}
return null;
}
/**
@ -2325,17 +2338,16 @@ public String getOurJID()
{
String jid = null;
if( connection != null && connection.getUser() != null)
return connection.getUser();
if (connection != null)
jid = connection.getUser();
if (jid == null)
{
//seems like the connection is not yet initialized so lets try
//to construct our jid ourselves.
String userID =
StringUtils.parseName(getAccountID().getUserID());
String serviceName =
StringUtils.parseServer(getAccountID().getUserID());
// seems like the connection is not yet initialized so lets try to
// construct our jid ourselves.
String accountIDUserID = getAccountID().getUserID();
String userID = StringUtils.parseName(accountIDUserID);
String serviceName = StringUtils.parseServer(accountIDUserID);
jid = userID + "@" + serviceName;
}
@ -2606,4 +2618,60 @@ private void setTrafficClass()
}
}
}
/**
* Gets the entity ID of the first Jitsi VideoBridge associated with
* {@link #connection} i.e. provided by the <tt>serviceName</tt> of
* <tt>connection</tt>.
*
* @return the entity ID of the first Jitsi VideoBridge associated with
* <tt>connection</tt>
*/
public String getJitsiVideoBridge()
{
XMPPConnection connection = getConnection();
if (connection != null)
{
ScServiceDiscoveryManager discoveryManager = getDiscoveryManager();
String serviceName = connection.getServiceName();
DiscoverItems discoverItems = null;
try
{
discoverItems = discoveryManager.discoverItems(serviceName);
}
catch (XMPPException xmppe)
{
}
if (discoverItems != null)
{
Iterator<DiscoverItems.Item> discoverItemIter
= discoverItems.getItems();
while (discoverItemIter.hasNext())
{
DiscoverItems.Item discoverItem = discoverItemIter.next();
String entityID = discoverItem.getEntityID();
DiscoverInfo discoverInfo = null;
try
{
discoverInfo = discoveryManager.discoverInfo(entityID);
}
catch (XMPPException xmppe)
{
}
if ((discoverInfo != null)
&& discoverInfo.containsFeature(
CobriConferenceIQ.NAMESPACE))
{
return entityID;
}
}
}
}
return null;
}
}

@ -0,0 +1,517 @@
/*
* Jitsi, the OpenSource Java VoIP and Instant Messaging client.
*
* Distributable under LGPL license.
* See terms of license at gnu.org.
*/
package net.java.sip.communicator.impl.protocol.jabber.extensions.cobri;
import java.util.*;
import net.java.sip.communicator.impl.protocol.jabber.extensions.jingle.*;
import org.jivesoftware.smack.packet.*;
/**
* Implements the Jitsi VideoBridge <tt>conference</tt> IQ.
*
* @author Lyubomir Marinov
*/
public class CobriConferenceIQ
extends IQ
{
/**
* The XML element name of the Jitsi VideoBridge <tt>conference</tt> IQ.
*/
public static final String ELEMENT_NAME = "conference";
/**
* The XML name of the <tt>id</tt> attribute of the Jitsi VideoBridge
* <tt>conference</tt> IQ which represents the value of the <tt>id</tt>
* property of <tt>CobriConferenceIQ</tt>.
*/
public static final String ID_ATTR_NAME = "id";
/**
* The XML namespace of the Jitsi VideoBridge <tt>conference</tt> IQ.
*/
public static final String NAMESPACE
= "http://jitsi.org/protocol/videobridge#conference";
/**
* The list of {@link Content}s included into this <tt>conference</tt> IQ.
*/
private final List<Content> contents = new LinkedList<Content>();
/**
* The ID of the conference represented by this IQ.
*/
private String id;
/**
* Initializes a new {@link Content} instance with a specific name and adds
* it to the list of <tt>Content</tt> instances included into this
* <tt>conference</tt> IQ.
*
* @param contentName the name which which the new <tt>Content</tt> instance
* is to be initialized
* @return <tt>true</tt> if the list of <tt>Content</tt> instances included
* into this <tt>conference</tt> IQ has been modified as a result of the
* method call; otherwise, <tt>false</tt>
*/
public boolean addContent(String contentName)
{
return addContent(new Content(contentName));
}
/**
* Adds a specific {@link Content} instance to the list of <tt>Content</tt>
* instances included into this <tt>conference</tt> IQ.
*
* @param content the <tt>Content</tt> instance to be added to this list of
* <tt>Content</tt> instances included into this <tt>conference</tt> IQ
* @return <tt>true</tt> if the list of <tt>Content</tt> instances included
* into this <tt>conference</tt> IQ has been modified as a result of the
* method call; otherwise, <tt>false</tt>
* @throws NullPointerException if the specified <tt>content</tt> is
* <tt>null</tt>
*/
public boolean addContent(Content content)
{
if (content == null)
throw new NullPointerException("content");
return contents.contains(content) ? false : contents.add(content);
}
public String getChildElementXML()
{
StringBuilder xml = new StringBuilder();
xml.append('<').append(ELEMENT_NAME);
xml.append(" xmlns='").append(NAMESPACE).append('\'');
String id = getID();
if (id != null)
xml.append(' ').append(ID_ATTR_NAME).append("='").append(id)
.append('\'');
List<Content> contents = getContents();
if (contents.size() == 0)
{
xml.append(" />");
}
else
{
xml.append('>');
for (Content content : contents)
content.toXML(xml);
xml.append("</").append(ELEMENT_NAME).append('>');
}
return xml.toString();
}
public Content getContent(String contentName)
{
for (Content content : getContents())
if (contentName.equals(content.getName()))
return content;
return null;
}
public List<Content> getContents()
{
return Collections.unmodifiableList(contents);
}
/**
* Gets the ID of the conference represented by this IQ.
*
* @return the ID of the conference represented by this IQ
*/
public String getID()
{
return id;
}
public Content getOrCreateContent(String contentName)
{
Content content = getContent(contentName);
if (content == null)
{
content = new Content(contentName);
addContent(content);
}
return content;
}
/**
* Removes a specific {@link Content} instance from the list of
* <tt>Content</tt> instances included into this <tt>conference</tt> IQ.
*
* @param content the <tt>Content</tt> instance to be removed from the list
* of <tt>Content</tt> instances included into this <tt>conference</tt> IQ
* @return <tt>true</tt> if the list of <tt>Content</tt> instances included
* into this <tt>conference</tt> IQ has been modified as a result of the
* method call; otherwise, <tt>false</tt>
*/
public boolean removeContent(Content content)
{
return contents.remove(content);
}
/**
* Sets the ID of the conference represented by this IQ.
*
* @param id the ID of the conference represented by this IQ
*/
public void setID(String id)
{
this.id = id;
}
/**
* Represents a <tt>channel</tt> included into a <tt>content</tt> of a Jitsi
* VideoBridge <tt>conference</tt> IQ.
*/
public static class Channel
{
/**
* The XML element name of a <tt>channel</tt> of a <tt>content</tt> of a
* Jitsi VideoBridge <tt>conference</tt> IQ.
*/
public static final String ELEMENT_NAME = "channel";
/**
* The XML name of the <tt>host</tt> attribute of a <tt>channel</tt> of
* a <tt>content</tt> of a <tt>conference</tt> IQ which represents the
* value of the <tt>host</tt> property of
* <tt>CobriConferenceIQ.Channel</tt>.
*/
public static final String HOST_ATTR_NAME = "host";
/**
* The XML name of the <tt>id</tt> attribute of a <tt>channel</tt> of a
* <tt>content</tt> of a <tt>conference</tt> IQ which represents the
* value of the <tt>id</tt> property of
* <tt>CobriConferenceIQ.Channel</tt>.
*/
public static final String ID_ATTR_NAME = "id";
/**
* The XML name of the <tt>rtcpport</tt> attribute of a <tt>channel</tt>
* of a <tt>content</tt> of a <tt>conference</tt> IQ which represents
* the value of the <tt>rtcpPort</tt> property of
* <tt>CobriConferenceIQ.Channel</tt>.
*/
public static final String RTCP_PORT_ATTR_NAME = "rtcpport";
/**
* The XML name of the <tt>rtpport</tt> attribute of a <tt>channel</tt>
* of a <tt>content</tt> of a <tt>conference</tt> IQ which represents
* the value of the <tt>rtpPort</tt> property of
* <tt>CobriConferenceIQ.Channel</tt>.
*/
public static final String RTP_PORT_ATTR_NAME = "rtpport";
/**
* The host of the <tt>channel</tt> represented by this instance.
*/
private String host;
/**
* The ID of the <tt>channel</tt> represented by this instance.
*/
private String id;
/**
* The <tt>payload-type</tt> elements defined by XEP-0167: Jingle RTP
* Sessions associated with this <tt>channel</tt>.
*/
private final List<PayloadTypePacketExtension> payloadTypes
= new ArrayList<PayloadTypePacketExtension>();
/**
* The RTCP port of the <tt>channel</tt> represented by this instance.
*/
private int rtcpPort;
/**
* The RTP port of the <tt>channel</tt> represented by this instance.
*/
private int rtpPort;
/**
* Adds a <tt>payload-type</tt> element defined by XEP-0167: Jingle RTP
* Sessions to this <tt>channel</tt>.
*
* @param payloadType the <tt>payload-type</tt> element to be added to
* this <tt>channel</tt>
* @return <tt>true</tt> if the list of <tt>payload-type</tt> elements
* associated with this <tt>channel</tt> has been modified as part of
* the method call; otherwise, <tt>false</tt>
* @throws NullPointerException if the specified <tt>payloadType</tt> is
* <tt>null</tt>
*/
public boolean addPayloadType(PayloadTypePacketExtension payloadType)
{
if (payloadType == null)
throw new NullPointerException("payloadType");
return
payloadTypes.contains(payloadType)
? false
: payloadTypes.add(payloadType);
}
public String getHost()
{
return host;
}
/**
* Gets the ID of the <tt>channel</tt> represented by this instance.
*
* @return the ID of the <tt>channel</tt> represented by this instance
*/
public String getID()
{
return id;
}
public List<PayloadTypePacketExtension> getPayloadTypes()
{
return Collections.unmodifiableList(payloadTypes);
}
public int getRTCPPort()
{
return rtcpPort;
}
public int getRTPPort()
{
return rtpPort;
}
/**
* Removes a <tt>payload-type</tt> element defined by XEP-0167: Jingle
* RTP Sessions from this <tt>channel</tt>.
*
* @param payloadType the <tt>payload-type</tt> element to be removed
* from this <tt>channel</tt>
* @return <tt>true</tt> if the list of <tt>payload-type</tt> elements
* associated with this <tt>channel</tt> has been modified as part of
* the method call; otherwise, <tt>false</tt>
*/
public boolean removePayloadType(PayloadTypePacketExtension payloadType)
{
return payloadTypes.remove(payloadType);
}
public void setHost(String host)
{
this.host = host;
}
/**
* Sets the ID of the <tt>channel</tt> represented by this instance.
*
* @param id the ID of the <tt>channel</tt> represented by this instance
*/
public void setID(String id)
{
this.id = id;
}
public void setRTCPPort(int rtcpPort)
{
this.rtcpPort = rtcpPort;
}
public void setRTPPort(int rtpPort)
{
this.rtpPort = rtpPort;
}
public void toXML(StringBuilder xml)
{
xml.append('<').append(ELEMENT_NAME);
String id = getID();
if (id != null)
xml.append(' ').append(ID_ATTR_NAME).append("='").append(id)
.append('\'');
String host = getHost();
if (host != null)
xml.append(' ').append(HOST_ATTR_NAME).append("='").append(host)
.append('\'');
int rtpPort = getRTPPort();
if (rtpPort > 0)
xml.append(' ').append(RTP_PORT_ATTR_NAME).append("='")
.append(rtpPort).append('\'');
int rtcpPort = getRTCPPort();
if (rtcpPort > 0)
xml.append(' ').append(RTCP_PORT_ATTR_NAME).append("='")
.append(rtcpPort).append('\'');
List<PayloadTypePacketExtension> payloadTypes = getPayloadTypes();
if (payloadTypes.size() == 0)
{
xml.append(" />");
}
else
{
xml.append('>');
for (PayloadTypePacketExtension payloadType : payloadTypes)
xml.append(payloadType.toXML());
xml.append("</").append(ELEMENT_NAME).append('>');
}
}
}
/**
* Represents a <tt>content</tt> included into a Jitsi VideoBridge
* <tt>conference</tt> IQ.
*/
public static class Content
{
/**
* The XML element name of a <tt>content</tt> of a Jitsi VideoBridge
* <tt>conference</tt> IQ.
*/
public static final String ELEMENT_NAME = "content";
/**
* The XML name of the <tt>name</tt> attribute of a <tt>content</tt> of
* a <tt>conference</tt> IQ which represents the <tt>name</tt> property
* of <tt>CobriConferenceIQ.Content</tt>.
*/
public static final String NAME_ATTR_NAME = "name";
/**
* The list of {@link Channel}s included into this <tt>content</tt> of a
* <tt>conference</tt> IQ.
*/
private final List<Channel> channels = new LinkedList<Channel>();
/**
* The name of the <tt>content</tt> represented by this instance.
*/
private String name;
/**
* Initializes a new <tt>Content</tt> instance without a name and
* channels.
*/
public Content()
{
}
/**
* Initializes a new <tt>Content</tt> instance with a specific name and
* without channels.
*
* @param name the name to initialize the new instance with
*/
public Content(String name)
{
setName(name);
}
public boolean addChannel(Channel channel)
{
if (channel == null)
throw new NullPointerException("channel");
return channels.contains(channel) ? false : channels.add(channel);
}
public Channel getChannel(int channelIndex)
{
return getChannels().get(channelIndex);
}
public Channel getChannel(String channelID)
{
for (Channel channel : getChannels())
if (channelID.equals(channel.getID()))
return channel;
return null;
}
public int getChannelCount()
{
return getChannels().size();
}
public List<Channel> getChannels()
{
return Collections.unmodifiableList(channels);
}
/**
* Gets the name of the <tt>content</tt> represented by this instance.
*
* @return the name of the <tt>content</tt> represented by this instance
*/
public String getName()
{
return name;
}
public boolean removeChannel(Channel channel)
{
return channels.remove(channel);
}
/**
* Sets the name of the <tt>content</tt> represented by this instance.
*
* @param name the name of the <tt>content</tt> represented by this
* instance
* @throws NullPointerException if the specified <tt>name</tt> is
* <tt>null</tt>
*/
public void setName(String name)
{
if (name == null)
throw new NullPointerException("name");
this.name = name;
}
public void toXML(StringBuilder xml)
{
xml.append('<').append(ELEMENT_NAME);
xml.append(' ').append(NAME_ATTR_NAME).append("='")
.append(getName()).append('\'');
List<Channel> channels = getChannels();
if (channels.size() == 0)
{
xml.append(" />");
}
else
{
xml.append('>');
for (Channel channel : channels)
channel.toXML(xml);
xml.append("</").append(ELEMENT_NAME).append('>');
}
}
}
}

@ -0,0 +1,187 @@
/*
* Jitsi, the OpenSource Java VoIP and Instant Messaging client.
*
* Distributable under LGPL license.
* See terms of license at gnu.org.
*/
package net.java.sip.communicator.impl.protocol.jabber.extensions.cobri;
import net.java.sip.communicator.impl.protocol.jabber.extensions.jingle.*;
import org.jivesoftware.smack.packet.*;
import org.jivesoftware.smack.provider.*;
import org.xmlpull.v1.*;
/**
* Implements an <tt>org.jivesoftware.smack.provider.IQProvider</tt> for the
* Jitsi VideoBridge extension <tt>CobriConferenceIQ</tt>.
*
* @author Lyubomir Marinov
*/
public class CobriIQProvider
implements IQProvider
{
/**
* Parses an IQ sub-document and creates an
* <tt>org.jivesoftware.smack.packet.IQ</tt> instance.
*
* @param parser an <tt>XmlPullParser</tt> which specifies the IQ
* sub-document to be parsed into a new <tt>IQ</tt> instance
* @return a new <tt>IQ</tt> instance parsed from the specified IQ
* sub-document
* @see IQProvider#parseIQ(XmlPullParser)
*/
public IQ parseIQ(XmlPullParser parser)
throws Exception
{
String namespace = parser.getNamespace();
IQ iq;
if (CobriConferenceIQ.ELEMENT_NAME.equals(parser.getName())
&& CobriConferenceIQ.NAMESPACE.equals(namespace))
{
CobriConferenceIQ conference = new CobriConferenceIQ();
String conferenceID
= parser.getAttributeValue("", CobriConferenceIQ.ID_ATTR_NAME);
if ((conferenceID != null) && (conferenceID.length() != 0))
conference.setID(conferenceID);
boolean done = false;
CobriConferenceIQ.Channel channel = null;
CobriConferenceIQ.Content content = null;
PacketExtensionProvider payloadTypePacketExtensionProvider = null;
while (!done)
{
switch (parser.next())
{
case XmlPullParser.END_TAG:
{
String name = parser.getName();
if (CobriConferenceIQ.ELEMENT_NAME.equals(name))
{
done = true;
}
else if (CobriConferenceIQ.Channel.ELEMENT_NAME
.equals(name))
{
content.addChannel(channel);
channel = null;
}
else if (CobriConferenceIQ.Content.ELEMENT_NAME
.equals(name))
{
conference.addContent(content);
content = null;
}
break;
}
case XmlPullParser.START_TAG:
{
String name = parser.getName();
if (CobriConferenceIQ.Channel.ELEMENT_NAME.equals(name))
{
channel = new CobriConferenceIQ.Channel();
String channelID
= parser.getAttributeValue(
"",
CobriConferenceIQ.Channel.ID_ATTR_NAME);
if ((channelID != null) && (channelID.length() != 0))
channel.setID(channelID);
String host
= parser.getAttributeValue(
"",
CobriConferenceIQ.Channel.HOST_ATTR_NAME);
if ((host != null) && (host.length() != 0))
channel.setHost(host);
String rtpPort
= parser.getAttributeValue(
"",
CobriConferenceIQ.Channel
.RTP_PORT_ATTR_NAME);
if ((rtpPort != null) && (rtpPort.length() != 0))
channel.setRTPPort(Integer.parseInt(rtpPort));
String rtcpPort
= parser.getAttributeValue(
"",
CobriConferenceIQ.Channel
.RTCP_PORT_ATTR_NAME);
if ((rtcpPort != null) && (rtcpPort.length() != 0))
channel.setRTCPPort(Integer.parseInt(rtcpPort));
}
else if (CobriConferenceIQ.Content.ELEMENT_NAME
.equals(name))
{
content = new CobriConferenceIQ.Content();
String contentName
= parser.getAttributeValue(
"",
CobriConferenceIQ.Content.NAME_ATTR_NAME);
if ((contentName != null)
&& (contentName.length() != 0))
content.setName(contentName);
}
else if (PayloadTypePacketExtension.ELEMENT_NAME.equals(
name))
{
/*
* The channel element of the Jitsi VideoBridge protocol
* reuses the payload-type element defined in XEP-0167:
* Jingle RTP Sessions.
*/
if (payloadTypePacketExtensionProvider == null)
{
payloadTypePacketExtensionProvider
= (PacketExtensionProvider)
ProviderManager.getInstance()
.getExtensionProvider(name, namespace);
}
if (payloadTypePacketExtensionProvider == null)
{
/*
* Well, the PacketExtensionProvider appears to have
* not been registered. Throw away the payload-type
* element.
*/
while ((XmlPullParser.END_TAG != parser.next())
|| !name.equals(parser.getName()));
}
else
{
PayloadTypePacketExtension payloadType
= (PayloadTypePacketExtension)
payloadTypePacketExtensionProvider
.parseExtension(parser);
if (payloadType != null)
channel.addPayloadType(payloadType);
}
}
break;
}
}
}
iq = conference;
}
else
iq = null;
return iq;
}
}
Loading…
Cancel
Save