diff options
author | steckbrief <steckbrief@chefmail.de> | 2017-08-07 12:57:57 +0200 |
---|---|---|
committer | steckbrief <steckbrief@chefmail.de> | 2017-08-07 12:57:57 +0200 |
commit | a892bb6f1685b84b74ba37e5a6a24ee8fb45eee7 (patch) | |
tree | f6d8036841f961dd987c2fb48e41983b327be049 /src/main/java/de/thedevstack/conversationsplus/xmpp | |
parent | be1992ce897d3b0551e545646a3e0f45cc6dd8c2 (diff) |
Simplifying introduction of new XEP implementations, implements FS#250 and FS#251 (Privacy and Security settings), refactoring of location of some interfaces
Diffstat (limited to '')
36 files changed, 886 insertions, 83 deletions
diff --git a/src/main/java/de/thedevstack/conversationsplus/xmpp/AbstractXep.java b/src/main/java/de/thedevstack/conversationsplus/xmpp/AbstractXep.java new file mode 100644 index 00000000..96cbeb3e --- /dev/null +++ b/src/main/java/de/thedevstack/conversationsplus/xmpp/AbstractXep.java @@ -0,0 +1,30 @@ +package de.thedevstack.conversationsplus.xmpp; + +/** + */ +public abstract class AbstractXep implements Xep { + protected boolean enabled = true; + + public AbstractXep() { + this(true); + } + + public AbstractXep(boolean enabled) { + this.enabled = enabled; + } + + @Override + public boolean isEnabled() { + return enabled; + } + + @Override + public final void enable() { + this.enabled = true; + } + + @Override + public final void disable() { + this.enabled = false; + } +} diff --git a/src/main/java/de/thedevstack/conversationsplus/xmpp/IqPacketHandler.java b/src/main/java/de/thedevstack/conversationsplus/xmpp/IqPacketHandler.java new file mode 100644 index 00000000..cfd5172e --- /dev/null +++ b/src/main/java/de/thedevstack/conversationsplus/xmpp/IqPacketHandler.java @@ -0,0 +1,12 @@ +package de.thedevstack.conversationsplus.xmpp; + +import de.thedevstack.conversationsplus.entities.Account; +import de.thedevstack.conversationsplus.xmpp.exceptions.IqPacketErrorException; +import de.thedevstack.conversationsplus.xmpp.stanzas.IqPacket; + +/** + * + */ +public interface IqPacketHandler { + void handleIqPacket(Account account, IqPacket packet) throws IqPacketErrorException; +} diff --git a/src/main/java/de/thedevstack/conversationsplus/xmpp/Xep.java b/src/main/java/de/thedevstack/conversationsplus/xmpp/Xep.java new file mode 100644 index 00000000..058f345e --- /dev/null +++ b/src/main/java/de/thedevstack/conversationsplus/xmpp/Xep.java @@ -0,0 +1,16 @@ +package de.thedevstack.conversationsplus.xmpp; + +/** + */ +public interface Xep { + boolean isEnabled(); + void enable(); + void disable(); + String xepNumber(); + String shortName(); + String name(); + String namespace(); + String featureNamespace(); + String elementName(); + IqPacketHandler handler(); +} diff --git a/src/main/java/de/thedevstack/conversationsplus/xmpp/XepRegistry.java b/src/main/java/de/thedevstack/conversationsplus/xmpp/XepRegistry.java new file mode 100644 index 00000000..89174c70 --- /dev/null +++ b/src/main/java/de/thedevstack/conversationsplus/xmpp/XepRegistry.java @@ -0,0 +1,51 @@ +package de.thedevstack.conversationsplus.xmpp; + +import java.util.Hashtable; + +import de.thedevstack.conversationsplus.xmpp.disco.FeatureRegistry; +import de.thedevstack.conversationsplus.xmpp.stanzas.IqPacketReceiver; + +/** + */ +public class XepRegistry { + private final Hashtable<String, Xep> xeps = new Hashtable<>(); + private static final XepRegistry INSTANCE = new XepRegistry(); + + public static void enable(String shortName) { + if (INSTANCE.xeps.containsKey(shortName)) { + Xep xep = INSTANCE.xeps.get(shortName); + xep.enable(); + FeatureRegistry.remove(xep); + IqPacketReceiver.getInstance().registerIqPacketHandler(xep); + } + } + + public static void disable(String shortName) { + if (INSTANCE.xeps.containsKey(shortName)) { + Xep xep = INSTANCE.xeps.get(shortName); + xep.disable(); + FeatureRegistry.remove(xep); + IqPacketReceiver.getInstance().unregisterIqPacketHandler(xep); + } + } + + public static void add(Xep xep) { + INSTANCE.xeps.put(xep.shortName(), xep); + if (xep.isEnabled()) { + FeatureRegistry.add(xep); + IqPacketReceiver.getInstance().registerIqPacketHandler(xep); + } + } + + public static void remove(Xep xep) { + INSTANCE.xeps.remove(xep.shortName()); + FeatureRegistry.remove(xep); + IqPacketReceiver.getInstance().unregisterIqPacketHandler(xep); + } + + public static XepRegistry getInstance() { + return INSTANCE; + } + + private XepRegistry() {} +} diff --git a/src/main/java/de/thedevstack/conversationsplus/xmpp/XmppConnection.java b/src/main/java/de/thedevstack/conversationsplus/xmpp/XmppConnection.java index 54db5346..2b366dbb 100644 --- a/src/main/java/de/thedevstack/conversationsplus/xmpp/XmppConnection.java +++ b/src/main/java/de/thedevstack/conversationsplus/xmpp/XmppConnection.java @@ -84,9 +84,11 @@ import de.thedevstack.conversationsplus.xmpp.mam.Mam; import de.thedevstack.conversationsplus.xmpp.stanzas.AbstractAcknowledgeableStanza; import de.thedevstack.conversationsplus.xmpp.stanzas.AbstractStanza; import de.thedevstack.conversationsplus.xmpp.stanzas.IqPacket; +import de.thedevstack.conversationsplus.xmpp.stanzas.IqPacketReceiver; import de.thedevstack.conversationsplus.xmpp.stanzas.MessagePacket; import de.thedevstack.conversationsplus.xmpp.stanzas.PresencePacket; import de.thedevstack.conversationsplus.xmpp.stanzas.csi.ActivePacket; +import de.thedevstack.conversationsplus.xmpp.stanzas.csi.Csi; import de.thedevstack.conversationsplus.xmpp.stanzas.csi.InactivePacket; import de.thedevstack.conversationsplus.xmpp.stanzas.streammgmt.AckPacket; import de.thedevstack.conversationsplus.xmpp.stanzas.streammgmt.EnablePacket; @@ -1092,7 +1094,7 @@ public class XmppConnection implements Runnable { } if (getFeatures().blocking() && !features.blockListRequested) { Log.d(Config.LOGTAG, account.getJid().toBareJid() + ": Requesting block list"); - this.sendIqPacket(getIqGenerator().generateGetBlockList(), mXmppConnectionService.getIqParser()); + this.sendIqPacket(getIqGenerator().generateGetBlockList(), IqPacketReceiver.getInstance().getLegacyIqParser()); } for (final OnAdvancedStreamFeaturesLoaded listener : advancedStreamFeaturesLoadedListeners) { listener.onAdvancedStreamFeaturesAvailable(account); @@ -1509,7 +1511,7 @@ public class XmppConnection implements Runnable { } public boolean csi() { - return connection.streamFeatures != null && connection.streamFeatures.hasChild("csi", "urn:xmpp:csi:0"); + return connection.streamFeatures != null && connection.streamFeatures.hasChild("csi", Csi.NAMESPACE); } public boolean pep() { diff --git a/src/main/java/de/thedevstack/conversationsplus/xmpp/disco/FeatureRegistry.java b/src/main/java/de/thedevstack/conversationsplus/xmpp/disco/FeatureRegistry.java new file mode 100644 index 00000000..1c266545 --- /dev/null +++ b/src/main/java/de/thedevstack/conversationsplus/xmpp/disco/FeatureRegistry.java @@ -0,0 +1,90 @@ +package de.thedevstack.conversationsplus.xmpp.disco; + +import android.util.Base64; + +import java.security.MessageDigest; +import java.security.NoSuchAlgorithmException; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; + +import de.thedevstack.conversationsplus.ConversationsPlusApplication; +import de.thedevstack.conversationsplus.crypto.axolotl.AxolotlService; +import de.thedevstack.conversationsplus.xmpp.Xep; +import de.thedevstack.conversationsplus.xmpp.chatstate.ChatState; +import de.tzur.conversations.Settings; + +/** + */ +public final class FeatureRegistry { + public static final String IDENTITY_TYPE = "phone"; + + private static final String[] LEGACY_FEATURES = { + "urn:xmpp:jingle:1", + "urn:xmpp:jingle:apps:file-transfer:3", + "urn:xmpp:jingle:transports:s5b:1", + "urn:xmpp:jingle:transports:ibb:1", + "http://jabber.org/protocol/muc", + "jabber:x:conference", + "http://jabber.org/protocol/caps", + "http://jabber.org/protocol/disco#info", + "urn:xmpp:avatar:metadata+notify", + "http://jabber.org/protocol/nick+notify", + ChatState.NAMESPACE, + AxolotlService.PEP_DEVICE_LIST+"+notify"}; + private static final String[] LEGACY_MESSAGE_CONFIRMATION_FEATURES = { + "urn:xmpp:chat-markers:0", + "urn:xmpp:receipts" + }; + private final List<String> features = new ArrayList<>(); + private static final FeatureRegistry INSTANCE = new FeatureRegistry(); + + public static void add(String featureNamespace) { + if (null != featureNamespace) { + INSTANCE.features.add(featureNamespace); + } + } + + public static void remove(String featureNamespace) { + if (null != featureNamespace && INSTANCE.features.contains(featureNamespace)) { + INSTANCE.features.remove(featureNamespace); + } + } + public static void add(Xep xep) { + add(xep.featureNamespace()); + } + + public static void remove(Xep xep) { + remove(xep.featureNamespace()); + } + + public static List<String> getFeatures() { + Collections.sort(INSTANCE.features); + return INSTANCE.features; + } + + public static String getCapHash() { + StringBuilder s = new StringBuilder(); + s.append("client/" + IDENTITY_TYPE + "//" + ConversationsPlusApplication.getNameAndVersion() + "<"); + MessageDigest md; + try { + md = MessageDigest.getInstance("SHA-1"); + } catch (NoSuchAlgorithmException e) { + return null; + } + + for (String feature : getFeatures()) { + s.append(feature + "<"); + } + byte[] sha1 = md.digest(s.toString().getBytes()); + return new String(Base64.encode(sha1, Base64.DEFAULT)); + } + + private FeatureRegistry() { + this.features.addAll(Arrays.asList(LEGACY_FEATURES)); + if (Settings.CONFIRM_MESSAGE_RECEIVED) { + this.features.addAll(Arrays.asList(LEGACY_MESSAGE_CONFIRMATION_FEATURES)); + } + } +} diff --git a/src/main/java/de/thedevstack/conversationsplus/xmpp/disco/ServiceDiscovery.java b/src/main/java/de/thedevstack/conversationsplus/xmpp/disco/ServiceDiscovery.java new file mode 100644 index 00000000..59a4212b --- /dev/null +++ b/src/main/java/de/thedevstack/conversationsplus/xmpp/disco/ServiceDiscovery.java @@ -0,0 +1,8 @@ +package de.thedevstack.conversationsplus.xmpp.disco; + +/** + */ +public interface ServiceDiscovery { + String NAMESPACE = "http://jabber.org/protocol/disco#info"; + String ELEMENT = "query"; +} diff --git a/src/main/java/de/thedevstack/conversationsplus/xmpp/disco/ServiceDiscoveryIqPacketGenerator.java b/src/main/java/de/thedevstack/conversationsplus/xmpp/disco/ServiceDiscoveryIqPacketGenerator.java new file mode 100644 index 00000000..8e1fc075 --- /dev/null +++ b/src/main/java/de/thedevstack/conversationsplus/xmpp/disco/ServiceDiscoveryIqPacketGenerator.java @@ -0,0 +1,38 @@ +package de.thedevstack.conversationsplus.xmpp.disco; + +import de.thedevstack.conversationsplus.ConversationsPlusApplication; +import de.thedevstack.conversationsplus.xml.Element; +import de.thedevstack.conversationsplus.xmpp.jid.Jid; +import de.thedevstack.conversationsplus.xmpp.stanzas.IqPacket; +import de.thedevstack.conversationsplus.xmpp.stanzas.IqPacketGenerator; + +/** + */ +public class ServiceDiscoveryIqPacketGenerator { + + public static IqPacket generateRequest(Jid jid) { + IqPacket request = IqPacketGenerator.generateIqGetPacket(); + request.setTo(jid); + request.query(ServiceDiscovery.NAMESPACE); + + return request; + } + + public static IqPacket generateResponse(IqPacket packet) { + IqPacket responsePacket = IqPacketGenerator.generateIqResultPacket(); + responsePacket.setTo(packet.getFrom()); + responsePacket.setId(packet.getId()); + + Element query = responsePacket.addChild(ServiceDiscovery.ELEMENT, ServiceDiscovery.NAMESPACE); + query.setAttribute("node", packet.query().getAttribute("node")); + final Element identity = query.addChild("identity"); + identity.setAttribute("category", "client"); + identity.setAttribute("type", FeatureRegistry.IDENTITY_TYPE); + identity.setAttribute("name", ConversationsPlusApplication.getNameAndVersion()); + for (final String feature : FeatureRegistry.getFeatures()) { + query.addChild("feature").setAttribute("var", feature); + } + + return responsePacket; + } +} diff --git a/src/main/java/de/thedevstack/conversationsplus/xmpp/disco/ServiceDiscoveryIqPacketHandler.java b/src/main/java/de/thedevstack/conversationsplus/xmpp/disco/ServiceDiscoveryIqPacketHandler.java new file mode 100644 index 00000000..6f1b0676 --- /dev/null +++ b/src/main/java/de/thedevstack/conversationsplus/xmpp/disco/ServiceDiscoveryIqPacketHandler.java @@ -0,0 +1,21 @@ +package de.thedevstack.conversationsplus.xmpp.disco; + +import de.thedevstack.conversationsplus.entities.Account; +import de.thedevstack.conversationsplus.utils.XmppSendUtil; +import de.thedevstack.conversationsplus.xmpp.IqPacketHandler; +import de.thedevstack.conversationsplus.xmpp.exceptions.IqPacketErrorException; +import de.thedevstack.conversationsplus.xmpp.exceptions.NotAllowedIqException; +import de.thedevstack.conversationsplus.xmpp.stanzas.IqPacket; + +/** + */ +public class ServiceDiscoveryIqPacketHandler implements IqPacketHandler { + @Override + public void handleIqPacket(Account account, IqPacket packet) throws IqPacketErrorException { + if (packet.getType() == IqPacket.TYPE.GET) { + XmppSendUtil.sendIqPacket(account, ServiceDiscoveryIqPacketGenerator.generateResponse(packet)); + } else { + throw new NotAllowedIqException(packet, "only type=get allowed for processing an service discovery (XEP-0030)"); + } + } +} diff --git a/src/main/java/de/thedevstack/conversationsplus/xmpp/disco/ServiceDiscoveryIqPacketParser.java b/src/main/java/de/thedevstack/conversationsplus/xmpp/disco/ServiceDiscoveryIqPacketParser.java new file mode 100644 index 00000000..0ea0d752 --- /dev/null +++ b/src/main/java/de/thedevstack/conversationsplus/xmpp/disco/ServiceDiscoveryIqPacketParser.java @@ -0,0 +1,15 @@ +package de.thedevstack.conversationsplus.xmpp.disco; + +import de.thedevstack.conversationsplus.entities.ServiceDiscoveryResult; +import de.thedevstack.conversationsplus.xmpp.stanzas.IqPacket; + +/** + */ +public class ServiceDiscoveryIqPacketParser { + public static ServiceDiscoveryResult parse(IqPacket packet) { + if (packet.getType() == IqPacket.TYPE.RESULT) { + return new ServiceDiscoveryResult(packet); + } + return null; + } +} diff --git a/src/main/java/de/thedevstack/conversationsplus/xmpp/disco/ServiceDiscoveryXep.java b/src/main/java/de/thedevstack/conversationsplus/xmpp/disco/ServiceDiscoveryXep.java new file mode 100644 index 00000000..6a21c71b --- /dev/null +++ b/src/main/java/de/thedevstack/conversationsplus/xmpp/disco/ServiceDiscoveryXep.java @@ -0,0 +1,51 @@ +package de.thedevstack.conversationsplus.xmpp.disco; + +import de.thedevstack.conversationsplus.xmpp.AbstractXep; +import de.thedevstack.conversationsplus.xmpp.IqPacketHandler; + +/** + */ +public class ServiceDiscoveryXep extends AbstractXep { + public ServiceDiscoveryXep() { + super(); + } + + public ServiceDiscoveryXep(boolean enabled) { + super(enabled); + } + + @Override + public String xepNumber() { + return "0030"; + } + + @Override + public String shortName() { + return "disco"; + } + + @Override + public String name() { + return "Service Discovery"; + } + + @Override + public String namespace() { + return ServiceDiscovery.NAMESPACE; + } + + @Override + public String featureNamespace() { + return ServiceDiscovery.NAMESPACE; + } + + @Override + public String elementName() { + return ServiceDiscovery.ELEMENT; + } + + @Override + public IqPacketHandler handler() { + return new ServiceDiscoveryIqPacketHandler(); + } +} diff --git a/src/main/java/de/thedevstack/conversationsplus/xmpp/exceptions/NotAllowedIqException.java b/src/main/java/de/thedevstack/conversationsplus/xmpp/exceptions/NotAllowedIqException.java new file mode 100644 index 00000000..45bf231a --- /dev/null +++ b/src/main/java/de/thedevstack/conversationsplus/xmpp/exceptions/NotAllowedIqException.java @@ -0,0 +1,11 @@ +package de.thedevstack.conversationsplus.xmpp.exceptions; + +import de.thedevstack.conversationsplus.xml.Element; + +/** + */ +public class NotAllowedIqException extends IqPacketErrorException { + public NotAllowedIqException(Element context, String errorMessage) { + super(context, errorMessage); + } +} diff --git a/src/main/java/de/thedevstack/conversationsplus/xmpp/iqversion/IqVersion.java b/src/main/java/de/thedevstack/conversationsplus/xmpp/iqversion/IqVersion.java new file mode 100644 index 00000000..e90ccb5a --- /dev/null +++ b/src/main/java/de/thedevstack/conversationsplus/xmpp/iqversion/IqVersion.java @@ -0,0 +1,9 @@ +package de.thedevstack.conversationsplus.xmpp.iqversion; + +/** + * + */ +public interface IqVersion { + String NAMESPACE = "jabber:iq:version"; + String ELEMENT = "query"; +} diff --git a/src/main/java/de/thedevstack/conversationsplus/xmpp/iqversion/IqVersionPacket.java b/src/main/java/de/thedevstack/conversationsplus/xmpp/iqversion/IqVersionPacket.java deleted file mode 100644 index a3cecdac..00000000 --- a/src/main/java/de/thedevstack/conversationsplus/xmpp/iqversion/IqVersionPacket.java +++ /dev/null @@ -1,23 +0,0 @@ -package de.thedevstack.conversationsplus.xmpp.iqversion; - -import android.os.Build; - -import de.thedevstack.conversationsplus.ConversationsPlusApplication; -import de.thedevstack.conversationsplus.xml.Element; -import de.thedevstack.conversationsplus.xmpp.stanzas.IqPacket; - -/** - * Representation of an software version packet as defined in XEP-0092. - * @see <a href="http://xmpp.org/extensions/xep-0092.html">http://xmpp.org/extensions/xep-0092.html</a> - */ -public class IqVersionPacket extends IqPacket { - public static final String NAMESPACE = "jabber:iq:version"; - - IqVersionPacket() { - super(IqPacket.TYPE.RESULT); - Element query = this.addChild("query", NAMESPACE); - query.addChild("name").setContent(ConversationsPlusApplication.getName()); - query.addChild("version").setContent(ConversationsPlusApplication.getVersion()); - query.addChild("os").setContent("Android " + Build.VERSION.RELEASE); - } -} diff --git a/src/main/java/de/thedevstack/conversationsplus/xmpp/iqversion/IqVersionPacketGenerator.java b/src/main/java/de/thedevstack/conversationsplus/xmpp/iqversion/IqVersionPacketGenerator.java index 97a7e90d..c4961c1d 100644 --- a/src/main/java/de/thedevstack/conversationsplus/xmpp/iqversion/IqVersionPacketGenerator.java +++ b/src/main/java/de/thedevstack/conversationsplus/xmpp/iqversion/IqVersionPacketGenerator.java @@ -1,6 +1,12 @@ package de.thedevstack.conversationsplus.xmpp.iqversion; +import android.os.Build; + +import de.thedevstack.conversationsplus.ConversationsPlusApplication; +import de.thedevstack.conversationsplus.ConversationsPlusPreferences; +import de.thedevstack.conversationsplus.xml.Element; import de.thedevstack.conversationsplus.xmpp.stanzas.IqPacket; +import de.thedevstack.conversationsplus.xmpp.stanzas.IqPacketGenerator; /** * Generates the IQ Packets for Software Version @@ -26,12 +32,17 @@ public final class IqVersionPacketGenerator { * @param packet the packet to respond to * @return */ - public static IqVersionPacket generateResponse(IqPacket packet) { - IqVersionPacket iqVersionPacket = new IqVersionPacket(); - iqVersionPacket.setTo(packet.getFrom()); - iqVersionPacket.setId(packet.getId()); + public static IqPacket generateResponse(IqPacket packet) { + IqPacket responsePacket = IqPacketGenerator.generateIqResultResponse(packet); + + Element query = responsePacket.addChild(IqVersion.ELEMENT, IqVersion.NAMESPACE); + query.addChild("name").setContent(ConversationsPlusApplication.getName()); + query.addChild("version").setContent(ConversationsPlusApplication.getVersion()); + if (ConversationsPlusPreferences.sendOsInformation()) { + query.addChild("os").setContent("Android " + Build.VERSION.RELEASE); + } - return iqVersionPacket; + return responsePacket; } private IqVersionPacketGenerator() {} diff --git a/src/main/java/de/thedevstack/conversationsplus/xmpp/iqversion/IqVersionPacketHandler.java b/src/main/java/de/thedevstack/conversationsplus/xmpp/iqversion/IqVersionPacketHandler.java new file mode 100644 index 00000000..7462d0cb --- /dev/null +++ b/src/main/java/de/thedevstack/conversationsplus/xmpp/iqversion/IqVersionPacketHandler.java @@ -0,0 +1,21 @@ +package de.thedevstack.conversationsplus.xmpp.iqversion; + +import de.thedevstack.conversationsplus.entities.Account; +import de.thedevstack.conversationsplus.utils.XmppSendUtil; +import de.thedevstack.conversationsplus.xmpp.IqPacketHandler; +import de.thedevstack.conversationsplus.xmpp.exceptions.IqPacketErrorException; +import de.thedevstack.conversationsplus.xmpp.exceptions.NotAllowedIqException; +import de.thedevstack.conversationsplus.xmpp.stanzas.IqPacket; + +/** + */ +public class IqVersionPacketHandler implements IqPacketHandler { + @Override + public void handleIqPacket(Account account, IqPacket packet) throws IqPacketErrorException { + if (packet.getType() == IqPacket.TYPE.GET) { + XmppSendUtil.sendIqPacket(account, IqVersionPacketGenerator.generateResponse(packet)); + } else { + throw new NotAllowedIqException(packet, "only type=get allowed for processing an Software Version (XEP-0092)"); + } + } +} diff --git a/src/main/java/de/thedevstack/conversationsplus/xmpp/iqversion/SoftwareVersionXep.java b/src/main/java/de/thedevstack/conversationsplus/xmpp/iqversion/SoftwareVersionXep.java new file mode 100644 index 00000000..9cd69bb2 --- /dev/null +++ b/src/main/java/de/thedevstack/conversationsplus/xmpp/iqversion/SoftwareVersionXep.java @@ -0,0 +1,51 @@ +package de.thedevstack.conversationsplus.xmpp.iqversion; + +import de.thedevstack.conversationsplus.xmpp.AbstractXep; +import de.thedevstack.conversationsplus.xmpp.IqPacketHandler; + +/** + */ +public class SoftwareVersionXep extends AbstractXep { + public SoftwareVersionXep() { + super(); + } + + public SoftwareVersionXep(boolean enabled) { + super(enabled); + } + + @Override + public String xepNumber() { + return "0092"; + } + + @Override + public String shortName() { + return "iq-version"; + } + + @Override + public String name() { + return "Software Version"; + } + + @Override + public String namespace() { + return IqVersion.NAMESPACE; + } + + @Override + public String featureNamespace() { + return IqVersion.NAMESPACE; + } + + @Override + public String elementName() { + return IqVersion.ELEMENT; + } + + @Override + public IqPacketHandler handler() { + return new IqVersionPacketHandler(); + } +} diff --git a/src/main/java/de/thedevstack/conversationsplus/xmpp/openpgp/OpenPgpXep.java b/src/main/java/de/thedevstack/conversationsplus/xmpp/openpgp/OpenPgpXep.java new file mode 100644 index 00000000..15229bf9 --- /dev/null +++ b/src/main/java/de/thedevstack/conversationsplus/xmpp/openpgp/OpenPgpXep.java @@ -0,0 +1,48 @@ +package de.thedevstack.conversationsplus.xmpp.openpgp; + +import de.thedevstack.conversationsplus.xmpp.AbstractXep; +import de.thedevstack.conversationsplus.xmpp.IqPacketHandler; + +/** + */ +public class OpenPgpXep extends AbstractXep { + public static final String ENCRYPTED_NAMESPACE = "jabber:x:encrypted"; + public static final String ENCRYPTED_ELEMENT = "x"; + public static final String SIGNED_NAMESPACE = "jabber:x:signed"; + public static final String SIGNED_ELEMENT = "x"; + + @Override + public String xepNumber() { + return "0027"; + } + + @Override + public String shortName() { + return "openpgp"; + } + + @Override + public String name() { + return "Current Jabber OpenPGP Usage"; + } + + @Override + public String namespace() { + return null; + } + + @Override + public String featureNamespace() { + return null; + } + + @Override + public String elementName() { + return null; + } + + @Override + public IqPacketHandler handler() { + return null; + } +} diff --git a/src/main/java/de/thedevstack/conversationsplus/xmpp/ping/Ping.java b/src/main/java/de/thedevstack/conversationsplus/xmpp/ping/Ping.java new file mode 100644 index 00000000..ac201c01 --- /dev/null +++ b/src/main/java/de/thedevstack/conversationsplus/xmpp/ping/Ping.java @@ -0,0 +1,8 @@ +package de.thedevstack.conversationsplus.xmpp.ping; + +/** + */ +public interface Ping { + String NAMESPACE = "urn:xmpp:ping"; + String ELEMENT = "ping"; +} diff --git a/src/main/java/de/thedevstack/conversationsplus/xmpp/ping/PingPacketHandler.java b/src/main/java/de/thedevstack/conversationsplus/xmpp/ping/PingPacketHandler.java new file mode 100644 index 00000000..14e8f57c --- /dev/null +++ b/src/main/java/de/thedevstack/conversationsplus/xmpp/ping/PingPacketHandler.java @@ -0,0 +1,22 @@ +package de.thedevstack.conversationsplus.xmpp.ping; + +import de.thedevstack.conversationsplus.entities.Account; +import de.thedevstack.conversationsplus.utils.XmppSendUtil; +import de.thedevstack.conversationsplus.xmpp.IqPacketHandler; +import de.thedevstack.conversationsplus.xmpp.exceptions.IqPacketErrorException; +import de.thedevstack.conversationsplus.xmpp.exceptions.NotAllowedIqException; +import de.thedevstack.conversationsplus.xmpp.stanzas.IqPacket; +import de.thedevstack.conversationsplus.xmpp.stanzas.IqPacketGenerator; + +/** + */ +public class PingPacketHandler implements IqPacketHandler { + @Override + public void handleIqPacket(Account account, IqPacket packet) throws IqPacketErrorException { + if (packet.getType() == IqPacket.TYPE.GET) { + XmppSendUtil.sendIqPacket(account, IqPacketGenerator.generateIqResultResponse(packet)); + } else { + throw new NotAllowedIqException(packet, "only type=get allowed for processing an XMPP Ping (XEP-0199)"); + } + } +} diff --git a/src/main/java/de/thedevstack/conversationsplus/xmpp/ping/PingXep.java b/src/main/java/de/thedevstack/conversationsplus/xmpp/ping/PingXep.java new file mode 100644 index 00000000..6036a64f --- /dev/null +++ b/src/main/java/de/thedevstack/conversationsplus/xmpp/ping/PingXep.java @@ -0,0 +1,51 @@ +package de.thedevstack.conversationsplus.xmpp.ping; + +import de.thedevstack.conversationsplus.xmpp.AbstractXep; +import de.thedevstack.conversationsplus.xmpp.IqPacketHandler; + +/** + */ +public class PingXep extends AbstractXep { + public PingXep() { + super(); + } + + public PingXep(boolean enabled) { + super(enabled); + } + + @Override + public String xepNumber() { + return "0199"; + } + + @Override + public String shortName() { + return "ping"; + } + + @Override + public String name() { + return "XMPP Ping"; + } + + @Override + public String namespace() { + return Ping.NAMESPACE; + } + + @Override + public String featureNamespace() { + return Ping.NAMESPACE; + } + + @Override + public String elementName() { + return Ping.ELEMENT; + } + + @Override + public IqPacketHandler handler() { + return new PingPacketHandler(); + } +} diff --git a/src/main/java/de/thedevstack/conversationsplus/xmpp/stanzas/ErrorIqPacket.java b/src/main/java/de/thedevstack/conversationsplus/xmpp/stanzas/ErrorIqPacket.java new file mode 100644 index 00000000..3f87202e --- /dev/null +++ b/src/main/java/de/thedevstack/conversationsplus/xmpp/stanzas/ErrorIqPacket.java @@ -0,0 +1,16 @@ +package de.thedevstack.conversationsplus.xmpp.stanzas; + +import de.thedevstack.conversationsplus.xml.Element; + +/** + */ +public class ErrorIqPacket extends IqPacket { + public final static String NAMESPACE = "urn:ietf:params:xml:ns:xmpp-stanzas"; + + public ErrorIqPacket(IqErrorCondition condition) { + super(IqPacket.TYPE.ERROR); + final Element error = this.addChild("error"); + error.setAttribute("type", condition.getType().toString()); + error.addChild(condition.toString(), NAMESPACE); + } +} diff --git a/src/main/java/de/thedevstack/conversationsplus/xmpp/stanzas/IqErrorCondition.java b/src/main/java/de/thedevstack/conversationsplus/xmpp/stanzas/IqErrorCondition.java new file mode 100644 index 00000000..688ea007 --- /dev/null +++ b/src/main/java/de/thedevstack/conversationsplus/xmpp/stanzas/IqErrorCondition.java @@ -0,0 +1,48 @@ +package de.thedevstack.conversationsplus.xmpp.stanzas; + +/** + */ +public enum IqErrorCondition { + BAD_REQUEST(IqErrorType.MODIFY), + CONFLICT(IqErrorType.CANCEL), + FEATURE_NOT_IMPLEMENTED(IqErrorType.CANCEL), + FORBIDDEN(IqErrorType.AUTH), + GONE(IqErrorType.MODIFY), + INTERNAL_SERVER_ERROR(IqErrorType.WAIT), + ITEM_NOT_FOUND(IqErrorType.CANCEL), + JID_MALFORMED(IqErrorType.MODIFY), + NOT_ACCEPTABLE(IqErrorType.MODIFY), + NOT_ALLOWED(IqErrorType.CANCEL), + NOT_AUTHORIZED(IqErrorType.AUTH), + PAYMENT_REQUIRED(IqErrorType.AUTH), + RECIPIENT_UNAVAILABLE(IqErrorType.WAIT), + REDIRECT(IqErrorType.MODIFY), + REGISTRATION_REQUIRED(IqErrorType.AUTH), + REMOTE_SERVER_NOT_FOUND(IqErrorType.CANCEL), + REMOTE_SERVER_TIMEOUT(IqErrorType.WAIT), + RESOURCE_CONSTRAINT(IqErrorType.WAIT), + SERVICE_UNAVAILABLE(IqErrorType.CANCEL), + SUBSCRIPTION_REQUIRED(IqErrorType.AUTH), + UNDEFINED_CONDITION(IqErrorType.CANCEL), + UNEXPECTED_REQUEST(IqErrorType.WAIT) + ; + + private IqErrorType type; + + IqErrorCondition(IqErrorType type) { + this.type = type; + } + + public IqErrorType getType() { + return type; + } + + public static IqErrorCondition fromString(String condition) { + return (null != condition) ? Enum.valueOf(IqErrorCondition.class, condition.toUpperCase().replaceAll("-", "_")) : null; + } + + @Override + public String toString() { + return super.toString().toLowerCase().replaceAll("_", "-"); + } +} diff --git a/src/main/java/de/thedevstack/conversationsplus/xmpp/stanzas/IqErrorType.java b/src/main/java/de/thedevstack/conversationsplus/xmpp/stanzas/IqErrorType.java new file mode 100644 index 00000000..4ebe0f41 --- /dev/null +++ b/src/main/java/de/thedevstack/conversationsplus/xmpp/stanzas/IqErrorType.java @@ -0,0 +1,12 @@ +package de.thedevstack.conversationsplus.xmpp.stanzas; + +/** + */ +public enum IqErrorType { + CANCEL, MODIFY, AUTH, WAIT; + + @Override + public String toString() { + return super.toString().toLowerCase(); + } +} diff --git a/src/main/java/de/thedevstack/conversationsplus/xmpp/stanzas/IqPacket.java b/src/main/java/de/thedevstack/conversationsplus/xmpp/stanzas/IqPacket.java index d86831e0..415d5de3 100644 --- a/src/main/java/de/thedevstack/conversationsplus/xmpp/stanzas/IqPacket.java +++ b/src/main/java/de/thedevstack/conversationsplus/xmpp/stanzas/IqPacket.java @@ -59,6 +59,10 @@ public class IqPacket extends AbstractAcknowledgeableStanza { } } + public Element getChildElement() { + return this.children.get(0); + } + public IqPacket generateResponse(final TYPE type) { final IqPacket packet = new IqPacket(type); packet.setTo(this.getFrom()); diff --git a/src/main/java/de/thedevstack/conversationsplus/xmpp/stanzas/IqPacketGenerator.java b/src/main/java/de/thedevstack/conversationsplus/xmpp/stanzas/IqPacketGenerator.java index 27e6607f..01204a96 100644 --- a/src/main/java/de/thedevstack/conversationsplus/xmpp/stanzas/IqPacketGenerator.java +++ b/src/main/java/de/thedevstack/conversationsplus/xmpp/stanzas/IqPacketGenerator.java @@ -1,5 +1,7 @@ package de.thedevstack.conversationsplus.xmpp.stanzas; +import de.thedevstack.conversationsplus.xml.Element; + /** * Created by tzur on 15.01.2016. */ @@ -21,8 +23,19 @@ public final class IqPacketGenerator { return generateIqPacket(IqPacket.TYPE.RESULT); } - public static IqPacket generateIqErrorPacket() { - return generateIqPacket(IqPacket.TYPE.ERROR); + public static IqPacket generateIqResultResponse(IqPacket packet) { + IqPacket responsePacket = generateIqResultPacket(); + responsePacket.setTo(packet.getFrom()); + responsePacket.setId(packet.getId()); + + return responsePacket; + } + + public static ErrorIqPacket generateIqErrorPacketResponse(IqErrorCondition condition, IqPacket packet) { + ErrorIqPacket errorPacket = new ErrorIqPacket(condition); + errorPacket.setTo(packet.getFrom()); + errorPacket.setId(packet.getId()); + return errorPacket; } private IqPacketGenerator() { diff --git a/src/main/java/de/thedevstack/conversationsplus/xmpp/stanzas/IqPacketReceiver.java b/src/main/java/de/thedevstack/conversationsplus/xmpp/stanzas/IqPacketReceiver.java new file mode 100644 index 00000000..bfae0355 --- /dev/null +++ b/src/main/java/de/thedevstack/conversationsplus/xmpp/stanzas/IqPacketReceiver.java @@ -0,0 +1,96 @@ +package de.thedevstack.conversationsplus.xmpp.stanzas; + +import java.util.Hashtable; + +import de.thedevstack.conversationsplus.entities.Account; +import de.thedevstack.conversationsplus.parser.IqParser; +import de.thedevstack.conversationsplus.utils.XmppConnectionServiceAccessor; +import de.thedevstack.conversationsplus.utils.XmppSendUtil; +import de.thedevstack.conversationsplus.xml.Element; +import de.thedevstack.conversationsplus.xmpp.IqPacketHandler; +import de.thedevstack.conversationsplus.xmpp.OnIqPacketReceived; +import de.thedevstack.conversationsplus.xmpp.Xep; +import de.thedevstack.conversationsplus.xmpp.exceptions.IqPacketErrorException; +import de.thedevstack.conversationsplus.xmpp.exceptions.NotAllowedIqException; + +/** + */ +public final class IqPacketReceiver implements OnIqPacketReceived { + private final Hashtable<String, IqPacketHandler> iqPacketHandlers = new Hashtable<>(); + private final IqParser legacyIqParser; + private static IqPacketReceiver INSTANCE; + + public synchronized static IqPacketReceiver getInstance() { + if (null == INSTANCE) { + IqPacketReceiver.INSTANCE = new IqPacketReceiver(); + } + return INSTANCE; + } + + private IqPacketReceiver() { + this.legacyIqParser = new IqParser(XmppConnectionServiceAccessor.xmppConnectionService); + } + + @Override + public void onIqPacketReceived(Account account, IqPacket packet) { + String key = generateKey(packet); + if (null != key && this.iqPacketHandlers.containsKey(key)) { + try { + IqPacketHandler iqPacketHandler = this.iqPacketHandlers.get(key); + iqPacketHandler.handleIqPacket(account, packet); + } catch (NotAllowedIqException e) { + ErrorIqPacket errorIqPacket = IqPacketGenerator.generateIqErrorPacketResponse(IqErrorCondition.NOT_ALLOWED, packet); + XmppSendUtil.sendIqPacket(account, errorIqPacket); + } catch (IqPacketErrorException e) { + + } + } else { + this.legacyIqParser.onIqPacketReceived(account, packet); + } + } + + public static String generateKey(IqPacket packet) { + Element childElement = packet.getChildElement(); + return generateKey(childElement.getName(), childElement.getNamespace()); + } + + public static String generateKey(String elementName, String xmlns) { + if (null == elementName && null == xmlns) { + return null; + } + return ((null != elementName) ? elementName : "") + ((null != xmlns) ? ("-" + xmlns) : ""); + } + + public void registerIqPacketHandler(String elementName, String xmlns, IqPacketHandler iqPacketHandler) { + String key = generateKey(elementName, xmlns); + if (null != key) { + this.iqPacketHandlers.put(key, iqPacketHandler); + } + } + + public void unregisterIqPacketHandler(String elementName, String xmlns) { + String key = generateKey(elementName, xmlns); + if (null != key && this.iqPacketHandlers.containsKey(key)) { + this.iqPacketHandlers.remove(key); + } + } + + public void registerIqPacketHandler(Xep xep) { + String key = generateKey(xep.elementName(), xep.namespace()); + if (null != key && null != xep.handler()) { + this.iqPacketHandlers.put(key, xep.handler()); + } + } + + public void unregisterIqPacketHandler(Xep xep) { + String key = generateKey(xep.elementName(), xep.namespace()); + if (null != key && this.iqPacketHandlers.containsKey(key)) { + this.iqPacketHandlers.remove(key); + } + } + + @Deprecated + public IqParser getLegacyIqParser() { + return this.legacyIqParser; + } +} diff --git a/src/main/java/de/thedevstack/conversationsplus/xmpp/stanzas/csi/ActivePacket.java b/src/main/java/de/thedevstack/conversationsplus/xmpp/stanzas/csi/ActivePacket.java index 47538a64..52b2e04d 100644 --- a/src/main/java/de/thedevstack/conversationsplus/xmpp/stanzas/csi/ActivePacket.java +++ b/src/main/java/de/thedevstack/conversationsplus/xmpp/stanzas/csi/ActivePacket.java @@ -5,6 +5,6 @@ import de.thedevstack.conversationsplus.xmpp.stanzas.AbstractStanza; public class ActivePacket extends AbstractStanza { public ActivePacket() { super("active"); - setAttribute("xmlns", "urn:xmpp:csi:0"); + setAttribute("xmlns", Csi.NAMESPACE); } } diff --git a/src/main/java/de/thedevstack/conversationsplus/xmpp/stanzas/csi/Csi.java b/src/main/java/de/thedevstack/conversationsplus/xmpp/stanzas/csi/Csi.java new file mode 100644 index 00000000..e002b093 --- /dev/null +++ b/src/main/java/de/thedevstack/conversationsplus/xmpp/stanzas/csi/Csi.java @@ -0,0 +1,7 @@ +package de.thedevstack.conversationsplus.xmpp.stanzas.csi; + +/** + */ +public interface Csi { + String NAMESPACE = "urn:xmpp:csi:0"; +} diff --git a/src/main/java/de/thedevstack/conversationsplus/xmpp/stanzas/csi/InactivePacket.java b/src/main/java/de/thedevstack/conversationsplus/xmpp/stanzas/csi/InactivePacket.java index ca5904a5..35486858 100644 --- a/src/main/java/de/thedevstack/conversationsplus/xmpp/stanzas/csi/InactivePacket.java +++ b/src/main/java/de/thedevstack/conversationsplus/xmpp/stanzas/csi/InactivePacket.java @@ -5,6 +5,6 @@ import de.thedevstack.conversationsplus.xmpp.stanzas.AbstractStanza; public class InactivePacket extends AbstractStanza { public InactivePacket() { super("inactive"); - setAttribute("xmlns", "urn:xmpp:csi:0"); + setAttribute("xmlns", Csi.NAMESPACE); } } diff --git a/src/main/java/de/thedevstack/conversationsplus/xmpp/time/EntityTime.java b/src/main/java/de/thedevstack/conversationsplus/xmpp/time/EntityTime.java new file mode 100644 index 00000000..7382f37a --- /dev/null +++ b/src/main/java/de/thedevstack/conversationsplus/xmpp/time/EntityTime.java @@ -0,0 +1,8 @@ +package de.thedevstack.conversationsplus.xmpp.time; + +/** + */ +public interface EntityTime { + String NAMESPACE = "urn:xmpp:time"; + String ELEMENT = "time"; +} diff --git a/src/main/java/de/thedevstack/conversationsplus/xmpp/time/EntityTimeXep.java b/src/main/java/de/thedevstack/conversationsplus/xmpp/time/EntityTimeXep.java new file mode 100644 index 00000000..fb721bce --- /dev/null +++ b/src/main/java/de/thedevstack/conversationsplus/xmpp/time/EntityTimeXep.java @@ -0,0 +1,51 @@ +package de.thedevstack.conversationsplus.xmpp.time; + +import de.thedevstack.conversationsplus.xmpp.AbstractXep; +import de.thedevstack.conversationsplus.xmpp.IqPacketHandler; + +/** + */ +public class EntityTimeXep extends AbstractXep { + public EntityTimeXep() { + super(); + } + + public EntityTimeXep(boolean enabled) { + super(enabled); + } + + @Override + public String xepNumber() { + return "0202"; + } + + @Override + public String shortName() { + return "time"; + } + + @Override + public String name() { + return "Entity Time"; + } + + @Override + public String namespace() { + return EntityTime.NAMESPACE; + } + + @Override + public String featureNamespace() { + return EntityTime.NAMESPACE; + } + + @Override + public String elementName() { + return EntityTime.ELEMENT; + } + + @Override + public IqPacketHandler handler() { + return new TimeIqPacketHandler(); + } +} diff --git a/src/main/java/de/thedevstack/conversationsplus/xmpp/time/TimeIqPacketHandler.java b/src/main/java/de/thedevstack/conversationsplus/xmpp/time/TimeIqPacketHandler.java new file mode 100644 index 00000000..961c649b --- /dev/null +++ b/src/main/java/de/thedevstack/conversationsplus/xmpp/time/TimeIqPacketHandler.java @@ -0,0 +1,21 @@ +package de.thedevstack.conversationsplus.xmpp.time; + +import de.thedevstack.conversationsplus.entities.Account; +import de.thedevstack.conversationsplus.utils.XmppSendUtil; +import de.thedevstack.conversationsplus.xmpp.IqPacketHandler; +import de.thedevstack.conversationsplus.xmpp.exceptions.IqPacketErrorException; +import de.thedevstack.conversationsplus.xmpp.exceptions.NotAllowedIqException; +import de.thedevstack.conversationsplus.xmpp.stanzas.IqPacket; + +/** + */ +public class TimeIqPacketHandler implements IqPacketHandler { + @Override + public void handleIqPacket(Account account, IqPacket packet) throws IqPacketErrorException { + if (packet.getType() == IqPacket.TYPE.GET) { + XmppSendUtil.sendIqPacket(account, TimePacketGenerator.generateResponse(packet)); + } else { + throw new NotAllowedIqException(packet, "only type=get allowed for processing an Entity Time (XEP-0202)"); + } + } +} diff --git a/src/main/java/de/thedevstack/conversationsplus/xmpp/time/TimePacket.java b/src/main/java/de/thedevstack/conversationsplus/xmpp/time/TimePacket.java deleted file mode 100644 index d8756d41..00000000 --- a/src/main/java/de/thedevstack/conversationsplus/xmpp/time/TimePacket.java +++ /dev/null @@ -1,35 +0,0 @@ -package de.thedevstack.conversationsplus.xmpp.time; - -import java.util.Locale; -import java.util.TimeZone; - -import de.thedevstack.conversationsplus.generator.AbstractGenerator; -import de.thedevstack.conversationsplus.xml.Element; -import de.thedevstack.conversationsplus.xmpp.stanzas.IqPacket; - -/** - * Representation of an software version packet as defined in XEP-0202. - * @see <a href="http://xmpp.org/extensions/xep-0202.html">http://xmpp.org/extensions/xep-0202.html</a> - */ -public class TimePacket extends IqPacket { - public static final String NAMESPACE = "urn:xmpp:time"; - - TimePacket() { - super(IqPacket.TYPE.RESULT); - Element time = this.addChild("time", NAMESPACE); - final long now = System.currentTimeMillis(); - time.addChild("utc").setContent(AbstractGenerator.getTimestamp(now)); - TimeZone ourTimezone = TimeZone.getDefault(); - long offsetSeconds = ourTimezone.getOffset(now) / 1000; - long offsetMinutes = Math.abs((offsetSeconds % 3600) / 60); - long offsetHours = offsetSeconds / 3600; - String hours; - if (offsetHours < 0) { - hours = String.format(Locale.US, "%03d", offsetHours); - } else { - hours = String.format(Locale.US, "%02d", offsetHours); - } - String minutes = String.format(Locale.US, "%02d", offsetMinutes); - time.addChild("tzo").setContent(hours + ":" + minutes); - } -} diff --git a/src/main/java/de/thedevstack/conversationsplus/xmpp/time/TimePacketGenerator.java b/src/main/java/de/thedevstack/conversationsplus/xmpp/time/TimePacketGenerator.java index 344beb9e..ef381d4d 100644 --- a/src/main/java/de/thedevstack/conversationsplus/xmpp/time/TimePacketGenerator.java +++ b/src/main/java/de/thedevstack/conversationsplus/xmpp/time/TimePacketGenerator.java @@ -1,7 +1,12 @@ package de.thedevstack.conversationsplus.xmpp.time; -import de.thedevstack.conversationsplus.xmpp.iqversion.IqVersionPacket; +import java.util.Locale; +import java.util.TimeZone; + +import de.thedevstack.conversationsplus.generator.AbstractGenerator; +import de.thedevstack.conversationsplus.xml.Element; import de.thedevstack.conversationsplus.xmpp.stanzas.IqPacket; +import de.thedevstack.conversationsplus.xmpp.stanzas.IqPacketGenerator; /** * Generates the IQ Packets for Entity Time @@ -26,12 +31,26 @@ public final class TimePacketGenerator { * @param packet * @return */ - public static TimePacket generateResponse(IqPacket packet) { - TimePacket timePacket = new TimePacket(); - timePacket.setTo(packet.getFrom()); - timePacket.setId(packet.getId()); + public static IqPacket generateResponse(IqPacket packet) { + IqPacket responsePacket = IqPacketGenerator.generateIqResultResponse(packet); + + Element time = responsePacket.addChild(EntityTime.ELEMENT, EntityTime.NAMESPACE); + final long now = System.currentTimeMillis(); + time.addChild("utc").setContent(AbstractGenerator.getTimestamp(now)); + TimeZone ourTimezone = TimeZone.getDefault(); + long offsetSeconds = ourTimezone.getOffset(now) / 1000; + long offsetMinutes = Math.abs((offsetSeconds % 3600) / 60); + long offsetHours = offsetSeconds / 3600; + String hours; + if (offsetHours < 0) { + hours = String.format(Locale.US, "%03d", offsetHours); + } else { + hours = String.format(Locale.US, "%02d", offsetHours); + } + String minutes = String.format(Locale.US, "%02d", offsetMinutes); + time.addChild("tzo").setContent(hours + ":" + minutes); - return timePacket; + return responsePacket; } private TimePacketGenerator() {} diff --git a/src/main/java/de/thedevstack/conversationsplus/xmpp/utils/ErrorIqPacketExceptionHelper.java b/src/main/java/de/thedevstack/conversationsplus/xmpp/utils/ErrorIqPacketExceptionHelper.java index bcc5e9dd..f3ac92dc 100644 --- a/src/main/java/de/thedevstack/conversationsplus/xmpp/utils/ErrorIqPacketExceptionHelper.java +++ b/src/main/java/de/thedevstack/conversationsplus/xmpp/utils/ErrorIqPacketExceptionHelper.java @@ -7,26 +7,26 @@ import de.thedevstack.conversationsplus.xmpp.exceptions.InternalServerErrorExcep import de.thedevstack.conversationsplus.xmpp.exceptions.IqPacketErrorException; import de.thedevstack.conversationsplus.xmpp.exceptions.ServiceUnavailableException; import de.thedevstack.conversationsplus.xmpp.exceptions.UndefinedConditionException; +import de.thedevstack.conversationsplus.xmpp.stanzas.ErrorIqPacket; +import de.thedevstack.conversationsplus.xmpp.stanzas.IqErrorCondition; /** - * Created by steckbrief on 22.08.2016. */ public final class ErrorIqPacketExceptionHelper { - private final static String ERROR_NAMESPACE = "urn:ietf:params:xml:ns:xmpp-stanzas"; public static void throwIqErrorException(Element errorIqPacket) throws IqPacketErrorException { Element packet = IqPacketParser.findChild(errorIqPacket, "error", "jabber:client"); if (null != packet) { - if (hasErrorElement(packet, "bad-request")) { + if (hasErrorElement(packet, IqErrorCondition.BAD_REQUEST.toString())) { throw new BadRequestIqErrorException(errorIqPacket, getErrorText(packet)); } - if (hasErrorElement(packet, "service-unavailable")) { + if (hasErrorElement(packet, IqErrorCondition.SERVICE_UNAVAILABLE.toString())) { throw new ServiceUnavailableException(errorIqPacket, getErrorText(packet)); } - if (hasErrorElement(packet, "internal-server-error")) { + if (hasErrorElement(packet, IqErrorCondition.INTERNAL_SERVER_ERROR.toString())) { throw new InternalServerErrorException(errorIqPacket, getErrorText(packet)); } - if (hasErrorElement(packet, "undefined-condition")) { + if (hasErrorElement(packet, IqErrorCondition.UNDEFINED_CONDITION.toString())) { throw new UndefinedConditionException(errorIqPacket, getErrorText(packet)); } } @@ -34,11 +34,11 @@ public final class ErrorIqPacketExceptionHelper { } private static boolean hasErrorElement(Element packet, String elementName) { - return null != IqPacketParser.findChild(packet, elementName, ERROR_NAMESPACE); + return null != IqPacketParser.findChild(packet, elementName, ErrorIqPacket.NAMESPACE); } private static String getErrorText(Element packet) { - return IqPacketParser.findChildContent(packet, "text", ERROR_NAMESPACE); + return IqPacketParser.findChildContent(packet, "text", ErrorIqPacket.NAMESPACE); } private ErrorIqPacketExceptionHelper() { |