DirectMucInvitationManager.java

  1. /**
  2.  *
  3.  * Copyright 2020 Paul Schaub.
  4.  *
  5.  * Licensed under the Apache License, Version 2.0 (the "License");
  6.  * you may not use this file except in compliance with the License.
  7.  * You may obtain a copy of the License at
  8.  *
  9.  *     http://www.apache.org/licenses/LICENSE-2.0
  10.  *
  11.  * Unless required by applicable law or agreed to in writing, software
  12.  * distributed under the License is distributed on an "AS IS" BASIS,
  13.  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  14.  * See the License for the specific language governing permissions and
  15.  * limitations under the License.
  16.  */
  17. package org.jivesoftware.smackx.muc;

  18. import java.util.ArrayList;
  19. import java.util.List;
  20. import java.util.Map;
  21. import java.util.WeakHashMap;

  22. import org.jivesoftware.smack.Manager;
  23. import org.jivesoftware.smack.SmackException;
  24. import org.jivesoftware.smack.XMPPConnection;
  25. import org.jivesoftware.smack.XMPPConnectionRegistry;
  26. import org.jivesoftware.smack.XMPPException;
  27. import org.jivesoftware.smack.filter.StanzaExtensionFilter;
  28. import org.jivesoftware.smack.packet.Message;
  29. import org.jivesoftware.smack.packet.MessageBuilder;
  30. import org.jivesoftware.smackx.disco.ServiceDiscoveryManager;
  31. import org.jivesoftware.smackx.muc.packet.GroupChatInvitation;

  32. import org.jxmpp.jid.EntityBareJid;

  33. /**
  34.  * Smacks API for XEP-0249: Direct MUC Invitations.
  35.  * Use this instead of {@link org.jivesoftware.smackx.muc.packet.MUCUser.Invite}.
  36.  *
  37.  * To invite a user to a group chat, use {@link #inviteToMuc(MultiUserChat, EntityBareJid)}.
  38.  *
  39.  * In order to listen for incoming invitations, register a {@link DirectMucInvitationListener} using
  40.  * {@link #addInvitationListener(DirectMucInvitationListener)}.
  41.  *
  42.  * @see <a href="https://xmpp.org/extensions/xep-0249.html">Direct MUC Invitations</a>
  43.  */
  44. public final class DirectMucInvitationManager extends Manager {

  45.     private static final Map<XMPPConnection, DirectMucInvitationManager> INSTANCES = new WeakHashMap<>();
  46.     private final List<DirectMucInvitationListener> directMucInvitationListeners = new ArrayList<>();
  47.     private final ServiceDiscoveryManager serviceDiscoveryManager;

  48.     static {
  49.         XMPPConnectionRegistry.addConnectionCreationListener(DirectMucInvitationManager::getInstanceFor);
  50.     }

  51.     public static synchronized DirectMucInvitationManager getInstanceFor(XMPPConnection connection) {
  52.         DirectMucInvitationManager manager = INSTANCES.get(connection);
  53.         if (manager == null) {
  54.             manager = new DirectMucInvitationManager(connection);
  55.             INSTANCES.put(connection, manager);
  56.         }
  57.         return manager;
  58.     }

  59.     private DirectMucInvitationManager(XMPPConnection connection) {
  60.         super(connection);
  61.         serviceDiscoveryManager = ServiceDiscoveryManager.getInstanceFor(connection);

  62.         connection().addAsyncStanzaListener(stanza -> {
  63.             GroupChatInvitation invitation = stanza.getExtension(GroupChatInvitation.class);
  64.             for (DirectMucInvitationListener listener : directMucInvitationListeners) {
  65.                 listener.invitationReceived(invitation, stanza);
  66.             }
  67.         }, new StanzaExtensionFilter(GroupChatInvitation.ELEMENT, GroupChatInvitation.NAMESPACE));
  68.         serviceDiscoveryManager.addFeature(GroupChatInvitation.NAMESPACE);
  69.     }

  70.     public void inviteToMuc(MultiUserChat muc, EntityBareJid user)
  71.             throws SmackException.NotConnectedException, InterruptedException {
  72.         inviteToMuc(muc, user, null, null, false, null);
  73.     }

  74.     public void inviteToMuc(MultiUserChat muc, EntityBareJid user, String password, String reason, boolean continueAsOneToOneChat, String thread)
  75.             throws SmackException.NotConnectedException, InterruptedException {
  76.         inviteToMuc(user, new GroupChatInvitation(muc.getRoom(), reason, password, continueAsOneToOneChat, thread));
  77.     }

  78.     public void inviteToMuc(EntityBareJid jid, GroupChatInvitation invitation) throws SmackException.NotConnectedException, InterruptedException {
  79.         Message invitationMessage = MessageBuilder.buildMessage()
  80.                 .to(jid)
  81.                 .addExtension(invitation)
  82.                 .build();
  83.         connection().sendStanza(invitationMessage);
  84.     }

  85.     public boolean userSupportsInvitations(EntityBareJid jid)
  86.             throws XMPPException.XMPPErrorException, SmackException.NotConnectedException, InterruptedException,
  87.             SmackException.NoResponseException {
  88.         return serviceDiscoveryManager.supportsFeature(jid, GroupChatInvitation.NAMESPACE);
  89.     }

  90.     public synchronized void addInvitationListener(DirectMucInvitationListener listener) {
  91.         directMucInvitationListeners.add(listener);
  92.     }

  93.     public synchronized void removeInvitationListener(DirectMucInvitationListener listener) {
  94.         directMucInvitationListeners.remove(listener);
  95.     }
  96. }