MessageFasteningManager.java

  1. /**
  2.  *
  3.  * Copyright 2019 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.message_fastening;

  18. import java.util.List;
  19. import java.util.WeakHashMap;

  20. import org.jivesoftware.smack.ConnectionCreationListener;
  21. import org.jivesoftware.smack.Manager;
  22. import org.jivesoftware.smack.XMPPConnection;
  23. import org.jivesoftware.smack.XMPPConnectionRegistry;
  24. import org.jivesoftware.smack.packet.MessageBuilder;

  25. import org.jivesoftware.smackx.disco.ServiceDiscoveryManager;
  26. import org.jivesoftware.smackx.message_fastening.element.FasteningElement;

  27. /**
  28.  * Smacks API for XEP-0422: Message Fastening.
  29.  * The API is still very bare bones, as the XEP intends Message Fastening to be used as a tool by other protocols.
  30.  *
  31.  * To enable / disable auto-announcing support for this feature, call {@link #setEnabledByDefault(boolean)} (default true).
  32.  *
  33.  * To fasten a payload to a previous message, create an {@link FasteningElement} using the builder provided by
  34.  * {@link FasteningElement#builder()}.
  35.  *
  36.  * You need to provide the {@link org.jivesoftware.smackx.sid.element.OriginIdElement} of the message you want to reference.
  37.  * Then add wrapped payloads using {@link FasteningElement.Builder#addWrappedPayloads(List)}
  38.  * and external payloads using {@link FasteningElement.Builder#addExternalPayloads(List)}.
  39.  *
  40.  * If you fastened some payloads onto the message previously and now want to replace the previous fastening, call
  41.  * {@link FasteningElement.Builder#isRemovingElement()}.
  42.  * Once you are finished, build the {@link FasteningElement} using {@link FasteningElement.Builder#build()} and add it to
  43.  * a stanza by calling {@link FasteningElement#applyTo(MessageBuilder)}.
  44.  *
  45.  * @see <a href="https://xmpp.org/extensions/xep-0422.html">XEP-0422: Message Fastening</a>
  46.  */
  47. public final class MessageFasteningManager extends Manager {

  48.     public static final String NAMESPACE = "urn:xmpp:fasten:0";

  49.     private static boolean ENABLED_BY_DEFAULT = false;

  50.     private static final WeakHashMap<XMPPConnection, MessageFasteningManager> INSTANCES = new WeakHashMap<>();

  51.     static {
  52.         XMPPConnectionRegistry.addConnectionCreationListener(new ConnectionCreationListener() {
  53.             @Override
  54.             public void connectionCreated(XMPPConnection connection) {
  55.                 if (ENABLED_BY_DEFAULT) {
  56.                     MessageFasteningManager.getInstanceFor(connection).announceSupport();
  57.                 }
  58.             }
  59.         });
  60.     }

  61.     private MessageFasteningManager(XMPPConnection connection) {
  62.         super(connection);
  63.     }

  64.     public static synchronized MessageFasteningManager getInstanceFor(XMPPConnection connection) {
  65.         MessageFasteningManager manager = INSTANCES.get(connection);
  66.         if (manager == null) {
  67.             manager = new MessageFasteningManager(connection);
  68.             INSTANCES.put(connection, manager);
  69.         }
  70.         return manager;
  71.     }

  72.     /**
  73.      * Enable or disable auto-announcing support for Message Fastening.
  74.      * Default is enabled.
  75.      *
  76.      * @param enabled enabled
  77.      */
  78.     public static synchronized void setEnabledByDefault(boolean enabled) {
  79.         ENABLED_BY_DEFAULT = enabled;
  80.     }

  81.     /**
  82.      * Announce support for Message Fastening via Service Discovery.
  83.      */
  84.     public void announceSupport() {
  85.         ServiceDiscoveryManager discoveryManager = ServiceDiscoveryManager.getInstanceFor(connection());
  86.         discoveryManager.addFeature(NAMESPACE);
  87.     }

  88.     /**
  89.      * Stop announcing support for Message Fastening.
  90.      */
  91.     public void stopAnnouncingSupport() {
  92.         ServiceDiscoveryManager discoveryManager = ServiceDiscoveryManager.getInstanceFor(connection());
  93.         discoveryManager.removeFeature(NAMESPACE);
  94.     }
  95. }