/**
   * Listens for a topic being removed from the space for either a MainMenuController or a
   * ChatroomController.
   */
  @Override
  public void notify(RemoteEvent remoteEvent) throws UnknownEventException, RemoteException {
    try {
      // Get the event that triggered the notification
      AvailabilityEvent availEvent = (AvailabilityEvent) remoteEvent;
      JMSTopicDeleted topicDeleted = (JMSTopicDeleted) availEvent.getEntry();

      if (isChatroomController) {
        // If the listener is for a ChatroomController, inform the given
        // chatroom that the chatroom's topic has been deleted
        chatroomController.handleTopicDeleted();
      } else {
        // If the listener is for a MainMenuController, remove the given
        // topic from the MainMenuController's topic list.
        DefaultTableModel topicTableModel = mainMenuController.getTopicTableModel();

        // Loop through all of the topics in the MainMenuController's
        // topic list and remove the one that was deleted
        for (int i = 0; i < topicTableModel.getRowCount(); i++) {
          UUID topicIdInTable = (UUID) topicTableModel.getValueAt(i, 3);
          JMSTopic topicRemoved = topicDeleted.getTopic();
          UUID topicDeletedId = topicRemoved.getId();

          if (topicIdInTable.equals(topicDeletedId)) {
            topicTableModel.removeRow(i);

            break;
          }
        }
      }
    } catch (Exception e) {
      System.err.println("Failed to remove topic from list or send notifications to users.");
      e.printStackTrace();
    }
  }
  /**
   * Checks if a topic has any null unique identifiers (base name, name, and UUID)
   *
   * @param topic
   * @return <code>true</code> if any unique identifier is null, otherwise <code>false</code>
   */
  private boolean isValidTopic(JMSTopic topic) {
    if (StringUtils.isNotBlank(topic.getBaseName())
        && StringUtils.isNotBlank(topic.getName())
        && topic.getId() != null) {
      return true;
    }

    return false;
  }
  /**
   * Whether or not a topic already exists in the space with the same base name or UUID.
   *
   * @param topic The topic to check if exists
   * @param transaction The transaction in which the check will take place
   * @return <code>true</code> if a match by either base name or UUID, otherwise <code>false</code>
   */
  private boolean topicExistsInSpace(JMSTopic topic, Transaction transaction) {
    try {
      JMSTopic template = new JMSTopic();
      template.setBaseName(topic.getBaseName());
      JMSTopic topicBaseNameMatch = (JMSTopic) space.readIfExists(template, transaction, 2000);

      template = new JMSTopic();
      template.setId(topic.getId());
      JMSTopic topicIdMatch = (JMSTopic) space.readIfExists(template, transaction, 2000);

      if (topicBaseNameMatch != null || topicIdMatch != null) {
        return true;
      }
    } catch (Exception e) {
      e.printStackTrace();
    }

    return false;
  }
  /**
   * Removes all users from a given topic.
   *
   * @param topic A topic to remove all of the users from.
   * @param transaction The transaction in which to run the delete
   */
  private void deleteAllTopicUsers(JMSTopic topic, Transaction transaction) {
    JMSTopicUser template = new JMSTopicUser(topic);

    try {
      while (space.readIfExists(template, transaction, 1000) != null) {
        space.takeIfExists(template, transaction, 1000);
      }
    } catch (RemoteException
        | UnusableEntryException
        | TransactionException
        | InterruptedException e) {
      System.err.println(
          "Failed to delete all users from Topic entitled: '"
              + topic.getName()
              + "' with ID: '"
              + topic.getId().toString()
              + "'");
      e.printStackTrace();
    }
  }
  /**
   * Removes a given user from a given topic
   *
   * @param topic The topic to remove the user from
   * @param user The user to remove from the topic
   */
  public void removeTopicUser(JMSTopic topic, JMSUser user) {
    try {
      Transaction transaction = TransactionHelper.getTransaction();

      boolean removed = false;
      JMSTopicUser template = new JMSTopicUser(topic, user);

      // If the space is in a bad state and has duplicate users in a
      // topic, this while loop ensures they are all removed
      while (space.takeIfExists(template, transaction, 1000) != null) {
        removed = true;
      }

      // Put a JMSTopicUserRemoved object in the space so listeners can
      // pick them up and remove them from other user's lists
      if (removed) {
        JMSTopicUserRemoved removedTopicUser =
            new JMSTopicUserRemoved(template.getTopic(), template.getUser());

        // Writes the JMSTopicUserRemoved with a 60 second lease, so
        // listeners have 60 seconds to act on it
        space.write(removedTopicUser, transaction, 1000l * 60l);
      }

      transaction.commit();
    } catch (RemoteException
        | UnusableEntryException
        | TransactionException
        | InterruptedException e) {
      System.err.println(
          "Failed to remove user from topic.  "
              + "User ID: '"
              + user.getId().toString()
              + "' && Topic ID: '"
              + topic.getId().toString()
              + "'");
      e.printStackTrace();
    }
  }