From a892bb6f1685b84b74ba37e5a6a24ee8fb45eee7 Mon Sep 17 00:00:00 2001 From: steckbrief Date: Mon, 7 Aug 2017 12:57:57 +0200 Subject: Simplifying introduction of new XEP implementations, implements FS#250 and FS#251 (Privacy and Security settings), refactoring of location of some interfaces --- .../xmpp/stanzas/ErrorIqPacket.java | 16 ++++ .../xmpp/stanzas/IqErrorCondition.java | 48 +++++++++++ .../xmpp/stanzas/IqErrorType.java | 12 +++ .../conversationsplus/xmpp/stanzas/IqPacket.java | 4 + .../xmpp/stanzas/IqPacketGenerator.java | 17 +++- .../xmpp/stanzas/IqPacketReceiver.java | 96 ++++++++++++++++++++++ .../xmpp/stanzas/csi/ActivePacket.java | 2 +- .../conversationsplus/xmpp/stanzas/csi/Csi.java | 7 ++ .../xmpp/stanzas/csi/InactivePacket.java | 2 +- 9 files changed, 200 insertions(+), 4 deletions(-) create mode 100644 src/main/java/de/thedevstack/conversationsplus/xmpp/stanzas/ErrorIqPacket.java create mode 100644 src/main/java/de/thedevstack/conversationsplus/xmpp/stanzas/IqErrorCondition.java create mode 100644 src/main/java/de/thedevstack/conversationsplus/xmpp/stanzas/IqErrorType.java create mode 100644 src/main/java/de/thedevstack/conversationsplus/xmpp/stanzas/IqPacketReceiver.java create mode 100644 src/main/java/de/thedevstack/conversationsplus/xmpp/stanzas/csi/Csi.java (limited to 'src/main/java/de/thedevstack/conversationsplus/xmpp/stanzas') 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 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); } } -- cgit v1.2.3