mirror of
https://codeberg.org/Mercury-IM/Smack
synced 2024-11-26 08:12:05 +01:00
Improved iqVersion code
including parsing and the version class.
This commit is contained in:
parent
8274a9f25b
commit
c9dd1cdc40
4 changed files with 144 additions and 59 deletions
|
@ -20,10 +20,15 @@ package org.jivesoftware.smackx.iqversion;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.WeakHashMap;
|
import java.util.WeakHashMap;
|
||||||
|
|
||||||
|
import org.jivesoftware.smack.SmackConfiguration;
|
||||||
|
import org.jivesoftware.smack.SmackException.NoResponseException;
|
||||||
import org.jivesoftware.smack.SmackException.NotConnectedException;
|
import org.jivesoftware.smack.SmackException.NotConnectedException;
|
||||||
|
import org.jivesoftware.smack.ConnectionCreationListener;
|
||||||
import org.jivesoftware.smack.XMPPConnection;
|
import org.jivesoftware.smack.XMPPConnection;
|
||||||
import org.jivesoftware.smack.Manager;
|
import org.jivesoftware.smack.Manager;
|
||||||
import org.jivesoftware.smack.PacketListener;
|
import org.jivesoftware.smack.PacketListener;
|
||||||
|
import org.jivesoftware.smack.XMPPConnectionRegistry;
|
||||||
|
import org.jivesoftware.smack.XMPPException.XMPPErrorException;
|
||||||
import org.jivesoftware.smack.filter.AndFilter;
|
import org.jivesoftware.smack.filter.AndFilter;
|
||||||
import org.jivesoftware.smack.filter.IQTypeFilter;
|
import org.jivesoftware.smack.filter.IQTypeFilter;
|
||||||
import org.jivesoftware.smack.filter.PacketFilter;
|
import org.jivesoftware.smack.filter.PacketFilter;
|
||||||
|
@ -53,7 +58,27 @@ public class VersionManager extends Manager {
|
||||||
|
|
||||||
private static final PacketFilter PACKET_FILTER = new AndFilter(new PacketTypeFilter(Version.class), IQTypeFilter.GET);
|
private static final PacketFilter PACKET_FILTER = new AndFilter(new PacketTypeFilter(Version.class), IQTypeFilter.GET);
|
||||||
|
|
||||||
private Version own_version;
|
private static Version defaultVersion;
|
||||||
|
|
||||||
|
private Version ourVersion = defaultVersion;
|
||||||
|
|
||||||
|
public static void setDefaultVersion(String name, String version) {
|
||||||
|
setDefaultVersion(name, version, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void setDefaultVersion(String name, String version, String os) {
|
||||||
|
defaultVersion = generateVersionFrom(name, version, os);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static boolean autoAppendSmackVersion = true;
|
||||||
|
|
||||||
|
static {
|
||||||
|
XMPPConnectionRegistry.addConnectionCreationListener(new ConnectionCreationListener() {
|
||||||
|
public void connectionCreated(XMPPConnection connection) {
|
||||||
|
VersionManager.getInstanceFor(connection);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
private VersionManager(final XMPPConnection connection) {
|
private VersionManager(final XMPPConnection connection) {
|
||||||
super(connection);
|
super(connection);
|
||||||
|
@ -67,13 +92,10 @@ public class VersionManager extends Manager {
|
||||||
* @throws NotConnectedException
|
* @throws NotConnectedException
|
||||||
*/
|
*/
|
||||||
public void processPacket(Packet packet) throws NotConnectedException {
|
public void processPacket(Packet packet) throws NotConnectedException {
|
||||||
if (own_version == null)
|
if (ourVersion == null)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
Version reply = new Version(own_version);
|
connection().sendPacket(Version.createResultFor(packet, ourVersion));
|
||||||
reply.setPacketID(packet.getPacketID());
|
|
||||||
reply.setTo(packet.getFrom());
|
|
||||||
connection().sendPacket(reply);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
, PACKET_FILTER);
|
, PACKET_FILTER);
|
||||||
|
@ -90,7 +112,49 @@ public class VersionManager extends Manager {
|
||||||
return versionManager;
|
return versionManager;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setVersion(Version v) {
|
public static void setAutoAppendSmackVersion(boolean autoAppendSmackVersion) {
|
||||||
own_version = v;
|
VersionManager.autoAppendSmackVersion = autoAppendSmackVersion;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setVersion(String name, String version) {
|
||||||
|
setVersion(name, version, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setVersion(String name, String version, String os) {
|
||||||
|
ourVersion = generateVersionFrom(name, version, os);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void unsetVersion() {
|
||||||
|
ourVersion = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isSupported(String jid) throws NoResponseException, XMPPErrorException,
|
||||||
|
NotConnectedException {
|
||||||
|
return ServiceDiscoveryManager.getInstanceFor(connection()).supportsFeature(jid,
|
||||||
|
Version.NAMESPACE);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Request version information from a given JID.
|
||||||
|
*
|
||||||
|
* @param jid
|
||||||
|
* @return the version information or {@code null} if not supported by JID
|
||||||
|
* @throws NoResponseException
|
||||||
|
* @throws XMPPErrorException
|
||||||
|
* @throws NotConnectedException
|
||||||
|
*/
|
||||||
|
public Version getVersion(String jid) throws NoResponseException, XMPPErrorException,
|
||||||
|
NotConnectedException {
|
||||||
|
if (!isSupported(jid)) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return connection().createPacketCollectorAndSend(new Version(jid)).nextResultOrThrow();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Version generateVersionFrom(String name, String version, String os) {
|
||||||
|
if (autoAppendSmackVersion) {
|
||||||
|
name += " (Smack " + SmackConfiguration.getVersion() + ')';
|
||||||
|
}
|
||||||
|
return new Version(name, version, os);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,7 +19,8 @@ package org.jivesoftware.smackx.iqversion.packet;
|
||||||
|
|
||||||
|
|
||||||
import org.jivesoftware.smack.packet.IQ;
|
import org.jivesoftware.smack.packet.IQ;
|
||||||
import org.jivesoftware.smack.util.StringUtils;
|
import org.jivesoftware.smack.packet.Packet;
|
||||||
|
import org.jivesoftware.smack.util.XmlStringBuilder;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A Version IQ packet, which is used by XMPP clients to discover version information
|
* A Version IQ packet, which is used by XMPP clients to discover version information
|
||||||
|
@ -50,10 +51,30 @@ import org.jivesoftware.smack.util.StringUtils;
|
||||||
public class Version extends IQ {
|
public class Version extends IQ {
|
||||||
public static final String NAMESPACE = "jabber:iq:version";
|
public static final String NAMESPACE = "jabber:iq:version";
|
||||||
|
|
||||||
private String name;
|
private final String name;
|
||||||
private String version;
|
private final String version;
|
||||||
private String os;
|
private String os;
|
||||||
|
|
||||||
|
public Version() {
|
||||||
|
name = null;
|
||||||
|
version = null;
|
||||||
|
setType(Type.get);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Request version IQ
|
||||||
|
*
|
||||||
|
* @param to the jid where to request version from
|
||||||
|
*/
|
||||||
|
public Version(String to) {
|
||||||
|
this();
|
||||||
|
setTo(to);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Version(String name, String version) {
|
||||||
|
this(name, version, null);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a new Version object with given details.
|
* Creates a new Version object with given details.
|
||||||
*
|
*
|
||||||
|
@ -62,6 +83,13 @@ public class Version extends IQ {
|
||||||
* @param os The operating system of the queried entity. This element is OPTIONAL.
|
* @param os The operating system of the queried entity. This element is OPTIONAL.
|
||||||
*/
|
*/
|
||||||
public Version(String name, String version, String os) {
|
public Version(String name, String version, String os) {
|
||||||
|
if (name == null)
|
||||||
|
{
|
||||||
|
throw new IllegalArgumentException("name must not be null");
|
||||||
|
}
|
||||||
|
if (version == null) {
|
||||||
|
throw new IllegalArgumentException("version must not be null");
|
||||||
|
}
|
||||||
this.setType(IQ.Type.result);
|
this.setType(IQ.Type.result);
|
||||||
this.name = name;
|
this.name = name;
|
||||||
this.version = version;
|
this.version = version;
|
||||||
|
@ -82,16 +110,6 @@ public class Version extends IQ {
|
||||||
return name;
|
return name;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Sets the natural-language name of the software. This message should only be
|
|
||||||
* invoked when parsing the XML and setting the property to a Version instance.
|
|
||||||
*
|
|
||||||
* @param name the natural-language name of the software.
|
|
||||||
*/
|
|
||||||
public void setName(String name) {
|
|
||||||
this.name = name;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the specific version of the software. This property will always be
|
* Returns the specific version of the software. This property will always be
|
||||||
* present in a result.
|
* present in a result.
|
||||||
|
@ -102,16 +120,6 @@ public class Version extends IQ {
|
||||||
return version;
|
return version;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Sets the specific version of the software. This message should only be
|
|
||||||
* invoked when parsing the XML and setting the property to a Version instance.
|
|
||||||
*
|
|
||||||
* @param version the specific version of the software.
|
|
||||||
*/
|
|
||||||
public void setVersion(String version) {
|
|
||||||
this.version = version;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the operating system of the queried entity. This property will always be
|
* Returns the operating system of the queried entity. This property will always be
|
||||||
* present in a result.
|
* present in a result.
|
||||||
|
@ -132,21 +140,23 @@ public class Version extends IQ {
|
||||||
this.os = os;
|
this.os = os;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getChildElementXML() {
|
@Override
|
||||||
StringBuilder buf = new StringBuilder();
|
public XmlStringBuilder getChildElementXML() {
|
||||||
buf.append("<query xmlns=\"");
|
XmlStringBuilder xml = new XmlStringBuilder();
|
||||||
buf.append(Version.NAMESPACE);
|
xml.halfOpenElement(IQ.QUERY_ELEMENT).xmlnsAttribute(NAMESPACE).rightAngelBracket();
|
||||||
buf.append("\">");
|
// Although not really optional elements, 'name' and 'version' are not set when sending a
|
||||||
if (name != null) {
|
// version request. So we must handle the case that those are 'null' here.
|
||||||
buf.append("<name>").append(StringUtils.escapeForXML(name)).append("</name>");
|
xml.optElement("name", name);
|
||||||
|
xml.optElement("version", version);
|
||||||
|
xml.optElement("os", os);
|
||||||
|
xml.closeElement(IQ.QUERY_ELEMENT);
|
||||||
|
return xml;
|
||||||
}
|
}
|
||||||
if (version != null) {
|
|
||||||
buf.append("<version>").append(StringUtils.escapeForXML(version)).append("</version>");
|
public static Version createResultFor(Packet request, Version version) {
|
||||||
}
|
Version result = new Version(version);
|
||||||
if (os != null) {
|
result.setPacketID(request.getPacketID());
|
||||||
buf.append("<os>").append(StringUtils.escapeForXML(os)).append("</os>");
|
result.setTo(request.getFrom());
|
||||||
}
|
return result;
|
||||||
buf.append("</query>");
|
|
||||||
return buf.toString();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,26 +24,36 @@ import org.xmlpull.v1.XmlPullParser;
|
||||||
|
|
||||||
public class VersionProvider implements IQProvider {
|
public class VersionProvider implements IQProvider {
|
||||||
public IQ parseIQ(XmlPullParser parser) throws Exception {
|
public IQ parseIQ(XmlPullParser parser) throws Exception {
|
||||||
|
assert (parser.getEventType() == XmlPullParser.START_TAG);
|
||||||
|
final int initalDepth = parser.getDepth();
|
||||||
String name = null, version = null, os = null;
|
String name = null, version = null, os = null;
|
||||||
|
|
||||||
boolean done = false;
|
outerloop: while (true) {
|
||||||
while (!done) {
|
|
||||||
int eventType = parser.next();
|
int eventType = parser.next();
|
||||||
|
switch (eventType) {
|
||||||
|
case XmlPullParser.START_TAG:
|
||||||
String tagName = parser.getName();
|
String tagName = parser.getName();
|
||||||
if (eventType == XmlPullParser.START_TAG) {
|
switch (tagName) {
|
||||||
if (tagName.equals("name")) {
|
case "name":
|
||||||
name = parser.nextText();
|
name = parser.nextText();
|
||||||
}
|
break;
|
||||||
else if (tagName.equals("version")) {
|
case "version":
|
||||||
version = parser.nextText();
|
version = parser.nextText();
|
||||||
}
|
break;
|
||||||
else if (tagName.equals("os")) {
|
case "os":
|
||||||
os = parser.nextText();
|
os = parser.nextText();
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
} else if (eventType == XmlPullParser.END_TAG && tagName.equals("query")) {
|
break;
|
||||||
done = true;
|
case XmlPullParser.END_TAG:
|
||||||
|
if (parser.getDepth() == initalDepth && parser.getName().equals(IQ.QUERY_ELEMENT)) {
|
||||||
|
break outerloop;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
if (name == null && version == null && os == null) {
|
||||||
|
return new Version();
|
||||||
|
}
|
||||||
return new Version(name, version, os);
|
return new Version(name, version, os);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -37,7 +37,8 @@ public class VersionTest {
|
||||||
DummyConnection con = new DummyConnection();
|
DummyConnection con = new DummyConnection();
|
||||||
|
|
||||||
// Enable version replys for this connection
|
// Enable version replys for this connection
|
||||||
VersionManager.getInstanceFor(con).setVersion(new Version("Test", "0.23", "DummyOS"));
|
VersionManager.setAutoAppendSmackVersion(false);
|
||||||
|
VersionManager.getInstanceFor(con).setVersion("Test", "0.23", "DummyOS");
|
||||||
IQ versionRequest = (IQ) PacketParserUtils.parseStanza(control);
|
IQ versionRequest = (IQ) PacketParserUtils.parseStanza(control);
|
||||||
|
|
||||||
assertTrue(versionRequest instanceof Version);
|
assertTrue(versionRequest instanceof Version);
|
||||||
|
|
Loading…
Reference in a new issue