JingleManager.java

  1. /**
  2.  *
  3.  * Copyright 2017-2021 Florian Schmaus
  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.jingle;

  18. import java.util.Map;
  19. import java.util.WeakHashMap;
  20. import java.util.concurrent.ConcurrentHashMap;
  21. import java.util.concurrent.ExecutorService;
  22. import java.util.concurrent.Executors;
  23. import java.util.logging.Level;
  24. import java.util.logging.Logger;

  25. import org.jivesoftware.smack.Manager;
  26. import org.jivesoftware.smack.XMPPConnection;
  27. import org.jivesoftware.smack.iqrequest.AbstractIqRequestHandler;
  28. import org.jivesoftware.smack.iqrequest.IQRequestHandler.Mode;
  29. import org.jivesoftware.smack.packet.IQ;
  30. import org.jivesoftware.smack.util.StringUtils;

  31. import org.jivesoftware.smackx.jingle.element.Jingle;
  32. import org.jivesoftware.smackx.jingle.element.JingleAction;
  33. import org.jivesoftware.smackx.jingle.element.JingleContent;
  34. import org.jivesoftware.smackx.jingle.element.JingleContentDescription;
  35. import org.jivesoftware.smackx.jingle.transports.jingle_ibb.JingleIBBTransportManager;
  36. import org.jivesoftware.smackx.jingle.transports.jingle_s5b.JingleS5BTransportManager;

  37. import org.jxmpp.jid.FullJid;

  38. public final class JingleManager extends Manager {

  39.     private static final Logger LOGGER = Logger.getLogger(JingleManager.class.getName());

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

  41.     private static final ExecutorService threadPool = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors());

  42.     public static ExecutorService getThreadPool() {
  43.         return threadPool;
  44.     }

  45.     public static synchronized JingleManager getInstanceFor(XMPPConnection connection) {
  46.         JingleManager jingleManager = INSTANCES.get(connection);
  47.         if (jingleManager == null) {
  48.             jingleManager = new JingleManager(connection);
  49.             INSTANCES.put(connection, jingleManager);
  50.         }
  51.         return jingleManager;
  52.     }

  53.     private final Map<String, JingleHandler> descriptionHandlers = new ConcurrentHashMap<>();

  54.     private final Map<FullJidAndSessionId, JingleSessionHandler> jingleSessionHandlers = new ConcurrentHashMap<>();

  55.     private final JingleUtil jutil;

  56.     private JingleManager(XMPPConnection connection) {
  57.         super(connection);

  58.         jutil = new JingleUtil(connection);

  59.         connection.registerIQRequestHandler(
  60.                 new AbstractIqRequestHandler(Jingle.ELEMENT, Jingle.NAMESPACE, IQ.Type.set, Mode.async) {
  61.                     @Override
  62.                     public IQ handleIQRequest(IQ iqRequest) {
  63.                         final Jingle jingle = (Jingle) iqRequest;

  64.                         FullJid fullFrom = jingle.getFrom().asFullJidOrThrow();
  65.                         String sid = jingle.getSid();
  66.                         FullJidAndSessionId fullJidAndSessionId = new FullJidAndSessionId(fullFrom, sid);

  67.                         JingleSessionHandler sessionHandler = jingleSessionHandlers.get(fullJidAndSessionId);
  68.                         if (sessionHandler != null) {
  69.                             // Handle existing session
  70.                             return sessionHandler.handleJingleSessionRequest(jingle);
  71.                         }

  72.                         if (jingle.getAction() == JingleAction.session_initiate) {

  73.                             JingleContent content = jingle.getContents().get(0);
  74.                             JingleContentDescription description = content.getDescription();
  75.                             JingleHandler jingleDescriptionHandler = descriptionHandlers.get(
  76.                                     description.getNamespace());

  77.                             if (jingleDescriptionHandler == null) {
  78.                                 // Unsupported Application
  79.                                 LOGGER.log(Level.WARNING, "Unsupported Jingle application.");
  80.                                 return jutil.createSessionTerminateUnsupportedApplications(fullFrom, sid);
  81.                             }
  82.                             return jingleDescriptionHandler.handleJingleRequest(jingle);
  83.                         }

  84.                         // Unknown session
  85.                         LOGGER.log(Level.WARNING, "Unknown session.");
  86.                         return jutil.createErrorUnknownSession(jingle);
  87.                     }
  88.                 });
  89.         // Register transports.
  90.         JingleTransportMethodManager transportMethodManager = JingleTransportMethodManager.getInstanceFor(connection);
  91.         transportMethodManager.registerTransportManager(JingleIBBTransportManager.getInstanceFor(connection));
  92.         transportMethodManager.registerTransportManager(JingleS5BTransportManager.getInstanceFor(connection));
  93.     }

  94.     public JingleHandler registerDescriptionHandler(String namespace, JingleHandler handler) {
  95.         return descriptionHandlers.put(namespace, handler);
  96.     }

  97.     public JingleSessionHandler registerJingleSessionHandler(FullJid otherJid, String sessionId, JingleSessionHandler sessionHandler) {
  98.         FullJidAndSessionId fullJidAndSessionId = new FullJidAndSessionId(otherJid, sessionId);
  99.         return jingleSessionHandlers.put(fullJidAndSessionId, sessionHandler);
  100.     }

  101.     public JingleSessionHandler unregisterJingleSessionHandler(FullJid otherJid, String sessionId, JingleSessionHandler sessionHandler) {
  102.         FullJidAndSessionId fullJidAndSessionId = new FullJidAndSessionId(otherJid, sessionId);
  103.         return jingleSessionHandlers.remove(fullJidAndSessionId);
  104.     }

  105.     public static String randomId() {
  106.         return StringUtils.randomString(24);
  107.     }
  108. }