MultiUserChatLightManager.java

  1. /**
  2.  *
  3.  * Copyright 2016 Fernando Ramirez
  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.muclight;

  18. import java.lang.ref.WeakReference;
  19. import java.util.ArrayList;
  20. import java.util.HashMap;
  21. import java.util.List;
  22. import java.util.Map;
  23. import java.util.WeakHashMap;

  24. import org.jivesoftware.smack.Manager;
  25. import org.jivesoftware.smack.SmackException.NoResponseException;
  26. import org.jivesoftware.smack.SmackException.NotConnectedException;
  27. import org.jivesoftware.smack.XMPPConnection;
  28. import org.jivesoftware.smack.XMPPException.XMPPErrorException;
  29. import org.jivesoftware.smack.filter.IQReplyFilter;
  30. import org.jivesoftware.smack.filter.StanzaFilter;
  31. import org.jivesoftware.smack.packet.IQ;

  32. import org.jivesoftware.smackx.disco.ServiceDiscoveryManager;
  33. import org.jivesoftware.smackx.disco.packet.DiscoverItems;
  34. import org.jivesoftware.smackx.muclight.element.MUCLightBlockingIQ;

  35. import org.jxmpp.jid.DomainBareJid;
  36. import org.jxmpp.jid.EntityBareJid;
  37. import org.jxmpp.jid.Jid;

  38. /**
  39.  * Multi-User Chat Light manager class.
  40.  *
  41.  * @author Fernando Ramirez
  42.  *
  43.  */
  44. public final class MultiUserChatLightManager extends Manager {

  45.     private static final Map<XMPPConnection, MultiUserChatLightManager> INSTANCES = new WeakHashMap<XMPPConnection, MultiUserChatLightManager>();

  46.     /**
  47.      * Get a instance of a MUC Light manager for the given connection.
  48.      *
  49.      * @param connection TODO javadoc me please
  50.      * @return a MUCLight manager.
  51.      */
  52.     public static synchronized MultiUserChatLightManager getInstanceFor(XMPPConnection connection) {
  53.         MultiUserChatLightManager multiUserChatLightManager = INSTANCES.get(connection);
  54.         if (multiUserChatLightManager == null) {
  55.             multiUserChatLightManager = new MultiUserChatLightManager(connection);
  56.             INSTANCES.put(connection, multiUserChatLightManager);
  57.         }
  58.         return multiUserChatLightManager;
  59.     }

  60.     /**
  61.      * A Map of MUC Light JIDs to instances. We use weak references for the
  62.      * values in order to allow those instances to get garbage collected.
  63.      */
  64.     private final Map<EntityBareJid, WeakReference<MultiUserChatLight>> multiUserChatLights = new HashMap<>();

  65.     private MultiUserChatLightManager(XMPPConnection connection) {
  66.         super(connection);
  67.     }

  68.     /**
  69.      * Obtain the MUC Light.
  70.      *
  71.      * @param jid TODO javadoc me please
  72.      * @return the MUCLight.
  73.      */
  74.     public synchronized MultiUserChatLight getMultiUserChatLight(EntityBareJid jid) {
  75.         WeakReference<MultiUserChatLight> weakRefMultiUserChat = multiUserChatLights.get(jid);
  76.         if (weakRefMultiUserChat == null) {
  77.             return createNewMucLightAndAddToMap(jid);
  78.         }
  79.         MultiUserChatLight multiUserChatLight = weakRefMultiUserChat.get();
  80.         if (multiUserChatLight == null) {
  81.             return createNewMucLightAndAddToMap(jid);
  82.         }
  83.         return multiUserChatLight;
  84.     }

  85.     private MultiUserChatLight createNewMucLightAndAddToMap(EntityBareJid jid) {
  86.         MultiUserChatLight multiUserChatLight = new MultiUserChatLight(connection(), jid);
  87.         multiUserChatLights.put(jid, new WeakReference<>(multiUserChatLight));
  88.         return multiUserChatLight;
  89.     }

  90.     /**
  91.      * Returns true if Multi-User Chat Light feature is supported by the server.
  92.      *
  93.      * @param mucLightService TODO javadoc me please
  94.      * @return true if Multi-User Chat Light feature is supported by the server.
  95.      * @throws NotConnectedException if the XMPP connection is not connected.
  96.      * @throws XMPPErrorException if there was an XMPP error returned.
  97.      * @throws NoResponseException if there was no response from the remote entity.
  98.      * @throws InterruptedException if the calling thread was interrupted.
  99.      */
  100.     public boolean isFeatureSupported(DomainBareJid mucLightService)
  101.             throws NoResponseException, XMPPErrorException, NotConnectedException, InterruptedException {
  102.         return ServiceDiscoveryManager.getInstanceFor(connection()).discoverInfo(mucLightService)
  103.                 .containsFeature(MultiUserChatLight.NAMESPACE);
  104.     }

  105.     /**
  106.      * Returns a List of the rooms the user occupies.
  107.      *
  108.      * @param mucLightService TODO javadoc me please
  109.      * @return a List of the rooms the user occupies.
  110.      * @throws XMPPErrorException if there was an XMPP error returned.
  111.      * @throws NoResponseException if there was no response from the remote entity.
  112.      * @throws NotConnectedException if the XMPP connection is not connected.
  113.      * @throws InterruptedException if the calling thread was interrupted.
  114.      */
  115.     public List<Jid> getOccupiedRooms(DomainBareJid mucLightService)
  116.             throws NoResponseException, XMPPErrorException, NotConnectedException, InterruptedException {
  117.         DiscoverItems result = ServiceDiscoveryManager.getInstanceFor(connection()).discoverItems(mucLightService);
  118.         List<DiscoverItems.Item> items = result.getItems();
  119.         List<Jid> answer = new ArrayList<>(items.size());

  120.         for (DiscoverItems.Item item : items) {
  121.             Jid mucLight = item.getEntityID();
  122.             answer.add(mucLight);
  123.         }

  124.         return answer;
  125.     }

  126.     /**
  127.      * Returns a collection with the XMPP addresses of the MUC Light services.
  128.      *
  129.      * @return a collection with the XMPP addresses of the MUC Light services.
  130.      * @throws XMPPErrorException if there was an XMPP error returned.
  131.      * @throws NoResponseException if there was no response from the remote entity.
  132.      * @throws NotConnectedException if the XMPP connection is not connected.
  133.      * @throws InterruptedException if the calling thread was interrupted.
  134.      */
  135.     public List<DomainBareJid> getLocalServices()
  136.             throws NoResponseException, XMPPErrorException, NotConnectedException, InterruptedException {
  137.         ServiceDiscoveryManager sdm = ServiceDiscoveryManager.getInstanceFor(connection());
  138.         return sdm.findServices(MultiUserChatLight.NAMESPACE, false, false);
  139.     }

  140.     /**
  141.      * Get users and rooms blocked.
  142.      *
  143.      * @param mucLightService TODO javadoc me please
  144.      * @return the list of users and rooms blocked
  145.      * @throws NoResponseException if there was no response from the remote entity.
  146.      * @throws XMPPErrorException if there was an XMPP error returned.
  147.      * @throws NotConnectedException if the XMPP connection is not connected.
  148.      * @throws InterruptedException if the calling thread was interrupted.
  149.      */
  150.     public List<Jid> getUsersAndRoomsBlocked(DomainBareJid mucLightService)
  151.             throws NoResponseException, XMPPErrorException, NotConnectedException, InterruptedException {
  152.         MUCLightBlockingIQ muclIghtBlockingIQResult = getBlockingList(mucLightService);

  153.         List<Jid> jids = new ArrayList<>();
  154.         if (muclIghtBlockingIQResult.getRooms() != null) {
  155.             jids.addAll(muclIghtBlockingIQResult.getRooms().keySet());
  156.         }

  157.         if (muclIghtBlockingIQResult.getUsers() != null) {
  158.             jids.addAll(muclIghtBlockingIQResult.getUsers().keySet());
  159.         }

  160.         return jids;
  161.     }

  162.     /**
  163.      * Get rooms blocked.
  164.      *
  165.      * @param mucLightService TODO javadoc me please
  166.      * @return the list of rooms blocked
  167.      * @throws NoResponseException if there was no response from the remote entity.
  168.      * @throws XMPPErrorException if there was an XMPP error returned.
  169.      * @throws NotConnectedException if the XMPP connection is not connected.
  170.      * @throws InterruptedException if the calling thread was interrupted.
  171.      */
  172.     public List<Jid> getRoomsBlocked(DomainBareJid mucLightService)
  173.             throws NoResponseException, XMPPErrorException, NotConnectedException, InterruptedException {
  174.         MUCLightBlockingIQ mucLightBlockingIQResult = getBlockingList(mucLightService);

  175.         List<Jid> jids = new ArrayList<>();
  176.         if (mucLightBlockingIQResult.getRooms() != null) {
  177.             jids.addAll(mucLightBlockingIQResult.getRooms().keySet());
  178.         }

  179.         return jids;
  180.     }

  181.     /**
  182.      * Get users blocked.
  183.      *
  184.      * @param mucLightService TODO javadoc me please
  185.      * @return the list of users blocked
  186.      * @throws NoResponseException if there was no response from the remote entity.
  187.      * @throws XMPPErrorException if there was an XMPP error returned.
  188.      * @throws NotConnectedException if the XMPP connection is not connected.
  189.      * @throws InterruptedException if the calling thread was interrupted.
  190.      */
  191.     public List<Jid> getUsersBlocked(DomainBareJid mucLightService)
  192.             throws NoResponseException, XMPPErrorException, NotConnectedException, InterruptedException {
  193.         MUCLightBlockingIQ mucLightBlockingIQResult = getBlockingList(mucLightService);

  194.         List<Jid> jids = new ArrayList<>();
  195.         if (mucLightBlockingIQResult.getUsers() != null) {
  196.             jids.addAll(mucLightBlockingIQResult.getUsers().keySet());
  197.         }

  198.         return jids;
  199.     }

  200.     private MUCLightBlockingIQ getBlockingList(DomainBareJid mucLightService)
  201.             throws NoResponseException, XMPPErrorException, InterruptedException, NotConnectedException {
  202.         MUCLightBlockingIQ mucLightBlockingIQ = new MUCLightBlockingIQ(null, null);
  203.         mucLightBlockingIQ.setType(IQ.Type.get);
  204.         mucLightBlockingIQ.setTo(mucLightService);

  205.         StanzaFilter responseFilter = new IQReplyFilter(mucLightBlockingIQ, connection());
  206.         IQ responseIq = connection().createStanzaCollectorAndSend(responseFilter, mucLightBlockingIQ)
  207.                 .nextResultOrThrow();
  208.         MUCLightBlockingIQ mucLightBlockingIQResult = (MUCLightBlockingIQ) responseIq;

  209.         return mucLightBlockingIQResult;
  210.     }

  211.     /**
  212.      * Block a room.
  213.      *
  214.      * @param mucLightService TODO javadoc me please
  215.      * @param roomJid TODO javadoc me please
  216.      * @throws NoResponseException if there was no response from the remote entity.
  217.      * @throws XMPPErrorException if there was an XMPP error returned.
  218.      * @throws NotConnectedException if the XMPP connection is not connected.
  219.      * @throws InterruptedException if the calling thread was interrupted.
  220.      */
  221.     public void blockRoom(DomainBareJid mucLightService, Jid roomJid)
  222.             throws NoResponseException, XMPPErrorException, NotConnectedException, InterruptedException {
  223.         HashMap<Jid, Boolean> rooms = new HashMap<>();
  224.         rooms.put(roomJid, false);
  225.         sendBlockRooms(mucLightService, rooms);
  226.     }

  227.     /**
  228.      * Block rooms.
  229.      *
  230.      * @param mucLightService TODO javadoc me please
  231.      * @param roomsJids TODO javadoc me please
  232.      * @throws NoResponseException if there was no response from the remote entity.
  233.      * @throws XMPPErrorException if there was an XMPP error returned.
  234.      * @throws NotConnectedException if the XMPP connection is not connected.
  235.      * @throws InterruptedException if the calling thread was interrupted.
  236.      */
  237.     public void blockRooms(DomainBareJid mucLightService, List<Jid> roomsJids)
  238.             throws NoResponseException, XMPPErrorException, NotConnectedException, InterruptedException {
  239.         HashMap<Jid, Boolean> rooms = new HashMap<>();
  240.         for (Jid jid : roomsJids) {
  241.             rooms.put(jid, false);
  242.         }
  243.         sendBlockRooms(mucLightService, rooms);
  244.     }

  245.     private void sendBlockRooms(DomainBareJid mucLightService, HashMap<Jid, Boolean> rooms)
  246.             throws NoResponseException, XMPPErrorException, InterruptedException, NotConnectedException {
  247.         MUCLightBlockingIQ mucLightBlockingIQ = new MUCLightBlockingIQ(rooms, null);
  248.         mucLightBlockingIQ.setType(IQ.Type.set);
  249.         mucLightBlockingIQ.setTo(mucLightService);
  250.         connection().sendIqRequestAndWaitForResponse(mucLightBlockingIQ);
  251.     }

  252.     /**
  253.      * Block a user.
  254.      *
  255.      * @param mucLightService TODO javadoc me please
  256.      * @param userJid TODO javadoc me please
  257.      * @throws NoResponseException if there was no response from the remote entity.
  258.      * @throws XMPPErrorException if there was an XMPP error returned.
  259.      * @throws NotConnectedException if the XMPP connection is not connected.
  260.      * @throws InterruptedException if the calling thread was interrupted.
  261.      */
  262.     public void blockUser(DomainBareJid mucLightService, Jid userJid)
  263.             throws NoResponseException, XMPPErrorException, NotConnectedException, InterruptedException {
  264.         HashMap<Jid, Boolean> users = new HashMap<>();
  265.         users.put(userJid, false);
  266.         sendBlockUsers(mucLightService, users);
  267.     }

  268.     /**
  269.      * Block users.
  270.      *
  271.      * @param mucLightService TODO javadoc me please
  272.      * @param usersJids TODO javadoc me please
  273.      * @throws NoResponseException if there was no response from the remote entity.
  274.      * @throws XMPPErrorException if there was an XMPP error returned.
  275.      * @throws NotConnectedException if the XMPP connection is not connected.
  276.      * @throws InterruptedException if the calling thread was interrupted.
  277.      */
  278.     public void blockUsers(DomainBareJid mucLightService, List<Jid> usersJids)
  279.             throws NoResponseException, XMPPErrorException, NotConnectedException, InterruptedException {
  280.         HashMap<Jid, Boolean> users = new HashMap<>();
  281.         for (Jid jid : usersJids) {
  282.             users.put(jid, false);
  283.         }
  284.         sendBlockUsers(mucLightService, users);
  285.     }

  286.     private void sendBlockUsers(DomainBareJid mucLightService, HashMap<Jid, Boolean> users)
  287.             throws NoResponseException, XMPPErrorException, InterruptedException, NotConnectedException {
  288.         MUCLightBlockingIQ mucLightBlockingIQ = new MUCLightBlockingIQ(null, users);
  289.         mucLightBlockingIQ.setType(IQ.Type.set);
  290.         mucLightBlockingIQ.setTo(mucLightService);
  291.         connection().sendIqRequestAndWaitForResponse(mucLightBlockingIQ);
  292.     }

  293.     /**
  294.      * Unblock a room.
  295.      *
  296.      * @param mucLightService TODO javadoc me please
  297.      * @param roomJid TODO javadoc me please
  298.      * @throws NoResponseException if there was no response from the remote entity.
  299.      * @throws XMPPErrorException if there was an XMPP error returned.
  300.      * @throws NotConnectedException if the XMPP connection is not connected.
  301.      * @throws InterruptedException if the calling thread was interrupted.
  302.      */
  303.     public void unblockRoom(DomainBareJid mucLightService, Jid roomJid)
  304.             throws NoResponseException, XMPPErrorException, NotConnectedException, InterruptedException {
  305.         HashMap<Jid, Boolean> rooms = new HashMap<>();
  306.         rooms.put(roomJid, true);
  307.         sendUnblockRooms(mucLightService, rooms);
  308.     }

  309.     /**
  310.      * Unblock rooms.
  311.      *
  312.      * @param mucLightService TODO javadoc me please
  313.      * @param roomsJids TODO javadoc me please
  314.      * @throws NoResponseException if there was no response from the remote entity.
  315.      * @throws XMPPErrorException if there was an XMPP error returned.
  316.      * @throws NotConnectedException if the XMPP connection is not connected.
  317.      * @throws InterruptedException if the calling thread was interrupted.
  318.      */
  319.     public void unblockRooms(DomainBareJid mucLightService, List<Jid> roomsJids)
  320.             throws NoResponseException, XMPPErrorException, NotConnectedException, InterruptedException {
  321.         HashMap<Jid, Boolean> rooms = new HashMap<>();
  322.         for (Jid jid : roomsJids) {
  323.             rooms.put(jid, true);
  324.         }
  325.         sendUnblockRooms(mucLightService, rooms);
  326.     }

  327.     private void sendUnblockRooms(DomainBareJid mucLightService, HashMap<Jid, Boolean> rooms)
  328.             throws NoResponseException, XMPPErrorException, InterruptedException, NotConnectedException {
  329.         MUCLightBlockingIQ mucLightBlockingIQ = new MUCLightBlockingIQ(rooms, null);
  330.         mucLightBlockingIQ.setType(IQ.Type.set);
  331.         mucLightBlockingIQ.setTo(mucLightService);
  332.         connection().sendIqRequestAndWaitForResponse(mucLightBlockingIQ);
  333.     }

  334.     /**
  335.      * Unblock a user.
  336.      *
  337.      * @param mucLightService TODO javadoc me please
  338.      * @param userJid TODO javadoc me please
  339.      * @throws NoResponseException if there was no response from the remote entity.
  340.      * @throws XMPPErrorException if there was an XMPP error returned.
  341.      * @throws NotConnectedException if the XMPP connection is not connected.
  342.      * @throws InterruptedException if the calling thread was interrupted.
  343.      */
  344.     public void unblockUser(DomainBareJid mucLightService, Jid userJid)
  345.             throws NoResponseException, XMPPErrorException, NotConnectedException, InterruptedException {
  346.         HashMap<Jid, Boolean> users = new HashMap<>();
  347.         users.put(userJid, true);
  348.         sendUnblockUsers(mucLightService, users);
  349.     }

  350.     /**
  351.      * Unblock users.
  352.      *
  353.      * @param mucLightService TODO javadoc me please
  354.      * @param usersJids TODO javadoc me please
  355.      * @throws NoResponseException if there was no response from the remote entity.
  356.      * @throws XMPPErrorException if there was an XMPP error returned.
  357.      * @throws NotConnectedException if the XMPP connection is not connected.
  358.      * @throws InterruptedException if the calling thread was interrupted.
  359.      */
  360.     public void unblockUsers(DomainBareJid mucLightService, List<Jid> usersJids)
  361.             throws NoResponseException, XMPPErrorException, NotConnectedException, InterruptedException {
  362.         HashMap<Jid, Boolean> users = new HashMap<>();
  363.         for (Jid jid : usersJids) {
  364.             users.put(jid, true);
  365.         }
  366.         sendUnblockUsers(mucLightService, users);
  367.     }

  368.     private void sendUnblockUsers(DomainBareJid mucLightService, HashMap<Jid, Boolean> users)
  369.             throws NoResponseException, XMPPErrorException, InterruptedException, NotConnectedException {
  370.         MUCLightBlockingIQ mucLightBlockingIQ = new MUCLightBlockingIQ(null, users);
  371.         mucLightBlockingIQ.setType(IQ.Type.set);
  372.         mucLightBlockingIQ.setTo(mucLightService);
  373.         connection().sendIqRequestAndWaitForResponse(mucLightBlockingIQ);
  374.     }

  375. }