mirror of
https://codeberg.org/Mercury-IM/Smack
synced 2024-11-22 14:22: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.WeakHashMap;
|
||||
|
||||
import org.jivesoftware.smack.SmackConfiguration;
|
||||
import org.jivesoftware.smack.SmackException.NoResponseException;
|
||||
import org.jivesoftware.smack.SmackException.NotConnectedException;
|
||||
import org.jivesoftware.smack.ConnectionCreationListener;
|
||||
import org.jivesoftware.smack.XMPPConnection;
|
||||
import org.jivesoftware.smack.Manager;
|
||||
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.IQTypeFilter;
|
||||
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 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) {
|
||||
super(connection);
|
||||
|
@ -67,13 +92,10 @@ public class VersionManager extends Manager {
|
|||
* @throws NotConnectedException
|
||||
*/
|
||||
public void processPacket(Packet packet) throws NotConnectedException {
|
||||
if (own_version == null)
|
||||
if (ourVersion == null)
|
||||
return;
|
||||
|
||||
Version reply = new Version(own_version);
|
||||
reply.setPacketID(packet.getPacketID());
|
||||
reply.setTo(packet.getFrom());
|
||||
connection().sendPacket(reply);
|
||||
connection().sendPacket(Version.createResultFor(packet, ourVersion));
|
||||
}
|
||||
}
|
||||
, PACKET_FILTER);
|
||||
|
@ -90,7 +112,49 @@ public class VersionManager extends Manager {
|
|||
return versionManager;
|
||||
}
|
||||
|
||||
public void setVersion(Version v) {
|
||||
own_version = v;
|
||||
public static void setAutoAppendSmackVersion(boolean autoAppendSmackVersion) {
|
||||
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.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
|
||||
|
@ -50,10 +51,30 @@ import org.jivesoftware.smack.util.StringUtils;
|
|||
public class Version extends IQ {
|
||||
public static final String NAMESPACE = "jabber:iq:version";
|
||||
|
||||
private String name;
|
||||
private String version;
|
||||
private final String name;
|
||||
private final String version;
|
||||
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.
|
||||
*
|
||||
|
@ -62,6 +83,13 @@ public class Version extends IQ {
|
|||
* @param os The operating system of the queried entity. This element is OPTIONAL.
|
||||
*/
|
||||
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.name = name;
|
||||
this.version = version;
|
||||
|
@ -82,16 +110,6 @@ public class Version extends IQ {
|
|||
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
|
||||
* present in a result.
|
||||
|
@ -102,16 +120,6 @@ public class Version extends IQ {
|
|||
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
|
||||
* present in a result.
|
||||
|
@ -132,21 +140,23 @@ public class Version extends IQ {
|
|||
this.os = os;
|
||||
}
|
||||
|
||||
public String getChildElementXML() {
|
||||
StringBuilder buf = new StringBuilder();
|
||||
buf.append("<query xmlns=\"");
|
||||
buf.append(Version.NAMESPACE);
|
||||
buf.append("\">");
|
||||
if (name != null) {
|
||||
buf.append("<name>").append(StringUtils.escapeForXML(name)).append("</name>");
|
||||
}
|
||||
if (version != null) {
|
||||
buf.append("<version>").append(StringUtils.escapeForXML(version)).append("</version>");
|
||||
}
|
||||
if (os != null) {
|
||||
buf.append("<os>").append(StringUtils.escapeForXML(os)).append("</os>");
|
||||
}
|
||||
buf.append("</query>");
|
||||
return buf.toString();
|
||||
@Override
|
||||
public XmlStringBuilder getChildElementXML() {
|
||||
XmlStringBuilder xml = new XmlStringBuilder();
|
||||
xml.halfOpenElement(IQ.QUERY_ELEMENT).xmlnsAttribute(NAMESPACE).rightAngelBracket();
|
||||
// Although not really optional elements, 'name' and 'version' are not set when sending a
|
||||
// version request. So we must handle the case that those are 'null' here.
|
||||
xml.optElement("name", name);
|
||||
xml.optElement("version", version);
|
||||
xml.optElement("os", os);
|
||||
xml.closeElement(IQ.QUERY_ELEMENT);
|
||||
return xml;
|
||||
}
|
||||
|
||||
public static Version createResultFor(Packet request, Version version) {
|
||||
Version result = new Version(version);
|
||||
result.setPacketID(request.getPacketID());
|
||||
result.setTo(request.getFrom());
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -24,26 +24,36 @@ import org.xmlpull.v1.XmlPullParser;
|
|||
|
||||
public class VersionProvider implements IQProvider {
|
||||
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;
|
||||
|
||||
boolean done = false;
|
||||
while (!done) {
|
||||
outerloop: while (true) {
|
||||
int eventType = parser.next();
|
||||
String tagName = parser.getName();
|
||||
if (eventType == XmlPullParser.START_TAG) {
|
||||
if (tagName.equals("name")) {
|
||||
switch (eventType) {
|
||||
case XmlPullParser.START_TAG:
|
||||
String tagName = parser.getName();
|
||||
switch (tagName) {
|
||||
case "name":
|
||||
name = parser.nextText();
|
||||
}
|
||||
else if (tagName.equals("version")) {
|
||||
break;
|
||||
case "version":
|
||||
version = parser.nextText();
|
||||
}
|
||||
else if (tagName.equals("os")) {
|
||||
break;
|
||||
case "os":
|
||||
os = parser.nextText();
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case XmlPullParser.END_TAG:
|
||||
if (parser.getDepth() == initalDepth && parser.getName().equals(IQ.QUERY_ELEMENT)) {
|
||||
break outerloop;
|
||||
}
|
||||
} else if (eventType == XmlPullParser.END_TAG && tagName.equals("query")) {
|
||||
done = true;
|
||||
}
|
||||
}
|
||||
if (name == null && version == null && os == null) {
|
||||
return new Version();
|
||||
}
|
||||
return new Version(name, version, os);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -37,7 +37,8 @@ public class VersionTest {
|
|||
DummyConnection con = new DummyConnection();
|
||||
|
||||
// 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);
|
||||
|
||||
assertTrue(versionRequest instanceof Version);
|
||||
|
|
Loading…
Reference in a new issue