Factor out a representation of XEP-0030 results
And the parser from Element to this representation.
This commit is contained in:
parent
0569a1e769
commit
fccce229c6
|
@ -0,0 +1,84 @@
|
||||||
|
package eu.siacs.conversations.entities;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
|
||||||
|
import eu.siacs.conversations.xml.Element;
|
||||||
|
import eu.siacs.conversations.xmpp.stanzas.IqPacket;
|
||||||
|
|
||||||
|
public class ServiceDiscoveryResult {
|
||||||
|
public static class Identity {
|
||||||
|
protected final String category;
|
||||||
|
protected final String type;
|
||||||
|
protected final String name;
|
||||||
|
|
||||||
|
public Identity(final String category, final String type, final String name) {
|
||||||
|
this.category = category;
|
||||||
|
this.type = type;
|
||||||
|
this.name = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Identity(final Element el) {
|
||||||
|
this.category = el.getAttribute("category");
|
||||||
|
this.type = el.getAttribute("type");
|
||||||
|
this.name = el.getAttribute("name");
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getCategory() {
|
||||||
|
return this.category;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getType() {
|
||||||
|
return this.type;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getName() {
|
||||||
|
return this.name;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected final List<Identity> identities;
|
||||||
|
protected final List<String> features;
|
||||||
|
|
||||||
|
public ServiceDiscoveryResult(final List<Identity> identities, final List<String> features) {
|
||||||
|
this.identities = identities;
|
||||||
|
this.features = features;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ServiceDiscoveryResult(final IqPacket packet) {
|
||||||
|
this.identities = new ArrayList<>();
|
||||||
|
this.features = new ArrayList<>();
|
||||||
|
|
||||||
|
final List<Element> elements = packet.query().getChildren();
|
||||||
|
|
||||||
|
for (final Element element : elements) {
|
||||||
|
if (element.getName().equals("identity")) {
|
||||||
|
Identity id = new Identity(element);
|
||||||
|
if (id.getType() != null && id.getCategory() != null) {
|
||||||
|
identities.add(id);
|
||||||
|
}
|
||||||
|
} else if (element.getName().equals("feature")) {
|
||||||
|
features.add(element.getAttribute("var"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<Identity> getIdentities() {
|
||||||
|
return this.identities;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<String> getFeatures() {
|
||||||
|
return this.features;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean hasIdentity(String category, String type) {
|
||||||
|
for(Identity id : this.getIdentities()) {
|
||||||
|
if((category == null || id.getCategory().equals(category)) &&
|
||||||
|
(type == null || id.getType().equals(type))) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
|
@ -58,6 +58,7 @@ import eu.siacs.conversations.crypto.sasl.SaslMechanism;
|
||||||
import eu.siacs.conversations.crypto.sasl.ScramSha1;
|
import eu.siacs.conversations.crypto.sasl.ScramSha1;
|
||||||
import eu.siacs.conversations.entities.Account;
|
import eu.siacs.conversations.entities.Account;
|
||||||
import eu.siacs.conversations.entities.Message;
|
import eu.siacs.conversations.entities.Message;
|
||||||
|
import eu.siacs.conversations.entities.ServiceDiscoveryResult;
|
||||||
import eu.siacs.conversations.generator.IqGenerator;
|
import eu.siacs.conversations.generator.IqGenerator;
|
||||||
import eu.siacs.conversations.services.XmppConnectionService;
|
import eu.siacs.conversations.services.XmppConnectionService;
|
||||||
import eu.siacs.conversations.utils.CryptoHelper;
|
import eu.siacs.conversations.utils.CryptoHelper;
|
||||||
|
@ -101,7 +102,7 @@ public class XmppConnection implements Runnable {
|
||||||
private boolean needsBinding = true;
|
private boolean needsBinding = true;
|
||||||
private boolean shouldAuthenticate = true;
|
private boolean shouldAuthenticate = true;
|
||||||
private Element streamFeatures;
|
private Element streamFeatures;
|
||||||
private final HashMap<Jid, Info> disco = new HashMap<>();
|
private final HashMap<Jid, ServiceDiscoveryResult> disco = new HashMap<>();
|
||||||
|
|
||||||
private String streamId = null;
|
private String streamId = null;
|
||||||
private int smVersion = 3;
|
private int smVersion = 3;
|
||||||
|
@ -1031,20 +1032,12 @@ public class XmppConnection implements Runnable {
|
||||||
if (packet.getType() == IqPacket.TYPE.RESULT) {
|
if (packet.getType() == IqPacket.TYPE.RESULT) {
|
||||||
boolean advancedStreamFeaturesLoaded;
|
boolean advancedStreamFeaturesLoaded;
|
||||||
synchronized (XmppConnection.this.disco) {
|
synchronized (XmppConnection.this.disco) {
|
||||||
final List<Element> elements = packet.query().getChildren();
|
ServiceDiscoveryResult result = new ServiceDiscoveryResult(packet);
|
||||||
final Info info = new Info();
|
for (final ServiceDiscoveryResult.Identity id : result.getIdentities()) {
|
||||||
for (final Element element : elements) {
|
if (mServerIdentity == Identity.UNKNOWN && id.getType().equals("im") &&
|
||||||
if (element.getName().equals("identity")) {
|
id.getCategory().equals("server") && id.getName() != null &&
|
||||||
String type = element.getAttribute("type");
|
jid.equals(account.getServer())) {
|
||||||
String category = element.getAttribute("category");
|
switch (id.getName()) {
|
||||||
String name = element.getAttribute("name");
|
|
||||||
if (type != null && category != null) {
|
|
||||||
info.identities.add(new Pair<>(category, type));
|
|
||||||
if (mServerIdentity == Identity.UNKNOWN
|
|
||||||
&& type.equals("im")
|
|
||||||
&& category.equals("server")) {
|
|
||||||
if (name != null && jid.equals(account.getServer())) {
|
|
||||||
switch (name) {
|
|
||||||
case "Prosody":
|
case "Prosody":
|
||||||
mServerIdentity = Identity.PROSODY;
|
mServerIdentity = Identity.PROSODY;
|
||||||
break;
|
break;
|
||||||
|
@ -1055,15 +1048,10 @@ public class XmppConnection implements Runnable {
|
||||||
mServerIdentity = Identity.SLACK;
|
mServerIdentity = Identity.SLACK;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
Log.d(Config.LOGTAG, account.getJid().toBareJid() + ": server name: " + name);
|
Log.d(Config.LOGTAG, account.getJid().toBareJid() + ": server name: " + id.getName());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
disco.put(jid, result);
|
||||||
} else if (element.getName().equals("feature")) {
|
|
||||||
info.features.add(element.getAttribute("var"));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
disco.put(jid, info);
|
|
||||||
advancedStreamFeaturesLoaded = disco.containsKey(account.getServer())
|
advancedStreamFeaturesLoaded = disco.containsKey(account.getServer())
|
||||||
&& disco.containsKey(account.getJid().toBareJid());
|
&& disco.containsKey(account.getJid().toBareJid());
|
||||||
}
|
}
|
||||||
|
@ -1316,8 +1304,8 @@ public class XmppConnection implements Runnable {
|
||||||
public List<Jid> findDiscoItemsByFeature(final String feature) {
|
public List<Jid> findDiscoItemsByFeature(final String feature) {
|
||||||
synchronized (this.disco) {
|
synchronized (this.disco) {
|
||||||
final List<Jid> items = new ArrayList<>();
|
final List<Jid> items = new ArrayList<>();
|
||||||
for (final Entry<Jid, Info> cursor : this.disco.entrySet()) {
|
for (final Entry<Jid, ServiceDiscoveryResult> cursor : this.disco.entrySet()) {
|
||||||
if (cursor.getValue().features.contains(feature)) {
|
if (cursor.getValue().getFeatures().contains(feature)) {
|
||||||
items.add(cursor.getKey());
|
items.add(cursor.getKey());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1344,11 +1332,11 @@ public class XmppConnection implements Runnable {
|
||||||
|
|
||||||
public String getMucServer() {
|
public String getMucServer() {
|
||||||
synchronized (this.disco) {
|
synchronized (this.disco) {
|
||||||
for (final Entry<Jid, Info> cursor : disco.entrySet()) {
|
for (final Entry<Jid, ServiceDiscoveryResult> cursor : disco.entrySet()) {
|
||||||
final Info value = cursor.getValue();
|
final ServiceDiscoveryResult value = cursor.getValue();
|
||||||
if (value.features.contains("http://jabber.org/protocol/muc")
|
if (value.getFeatures().contains("http://jabber.org/protocol/muc")
|
||||||
&& !value.features.contains("jabber:iq:gateway")
|
&& !value.getFeatures().contains("jabber:iq:gateway")
|
||||||
&& !value.identities.contains(new Pair<>("conference", "irc"))) {
|
&& !value.hasIdentity("conference", "irc")) {
|
||||||
return cursor.getKey().toString();
|
return cursor.getKey().toString();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1411,11 +1399,6 @@ public class XmppConnection implements Runnable {
|
||||||
return mServerIdentity;
|
return mServerIdentity;
|
||||||
}
|
}
|
||||||
|
|
||||||
private class Info {
|
|
||||||
public final ArrayList<String> features = new ArrayList<>();
|
|
||||||
public final ArrayList<Pair<String,String>> identities = new ArrayList<>();
|
|
||||||
}
|
|
||||||
|
|
||||||
private class UnauthorizedException extends IOException {
|
private class UnauthorizedException extends IOException {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -1450,7 +1433,7 @@ public class XmppConnection implements Runnable {
|
||||||
private boolean hasDiscoFeature(final Jid server, final String feature) {
|
private boolean hasDiscoFeature(final Jid server, final String feature) {
|
||||||
synchronized (XmppConnection.this.disco) {
|
synchronized (XmppConnection.this.disco) {
|
||||||
return connection.disco.containsKey(server) &&
|
return connection.disco.containsKey(server) &&
|
||||||
connection.disco.get(server).features.contains(feature);
|
connection.disco.get(server).getFeatures().contains(feature);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1478,12 +1461,12 @@ public class XmppConnection implements Runnable {
|
||||||
public boolean pep() {
|
public boolean pep() {
|
||||||
synchronized (XmppConnection.this.disco) {
|
synchronized (XmppConnection.this.disco) {
|
||||||
final Pair<String, String> needle = new Pair<>("pubsub", "pep");
|
final Pair<String, String> needle = new Pair<>("pubsub", "pep");
|
||||||
Info info = disco.get(account.getServer());
|
ServiceDiscoveryResult info = disco.get(account.getServer());
|
||||||
if (info != null && info.identities.contains(needle)) {
|
if (info != null && info.hasIdentity("pubsub", "pep")) {
|
||||||
return true;
|
return true;
|
||||||
} else {
|
} else {
|
||||||
info = disco.get(account.getJid().toBareJid());
|
info = disco.get(account.getJid().toBareJid());
|
||||||
return info != null && info.identities.contains(needle);
|
return info != null && info.hasIdentity("pubsub", "pep");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue