001/**
002 *
003 * Copyright © 2015-2020 Florian Schmaus
004 *
005 * Licensed under the Apache License, Version 2.0 (the "License");
006 * you may not use this file except in compliance with the License.
007 * You may obtain a copy of the License at
008 *
009 *     http://www.apache.org/licenses/LICENSE-2.0
010 *
011 * Unless required by applicable law or agreed to in writing, software
012 * distributed under the License is distributed on an "AS IS" BASIS,
013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014 * See the License for the specific language governing permissions and
015 * limitations under the License.
016 */
017package org.jivesoftware.smackx.muc.bookmarkautojoin;
018
019import java.util.List;
020import java.util.Map;
021import java.util.WeakHashMap;
022import java.util.logging.Level;
023import java.util.logging.Logger;
024
025import org.jivesoftware.smack.ConnectionCreationListener;
026import org.jivesoftware.smack.ConnectionListener;
027import org.jivesoftware.smack.Manager;
028import org.jivesoftware.smack.SmackException.NoResponseException;
029import org.jivesoftware.smack.SmackException.NotConnectedException;
030import org.jivesoftware.smack.XMPPConnection;
031import org.jivesoftware.smack.XMPPConnectionRegistry;
032import org.jivesoftware.smack.XMPPException.XMPPErrorException;
033
034import org.jivesoftware.smackx.bookmarks.BookmarkManager;
035import org.jivesoftware.smackx.bookmarks.BookmarkedConference;
036import org.jivesoftware.smackx.muc.MultiUserChat;
037import org.jivesoftware.smackx.muc.MultiUserChat.MucCreateConfigFormHandle;
038import org.jivesoftware.smackx.muc.MultiUserChatException.NotAMucServiceException;
039import org.jivesoftware.smackx.muc.MultiUserChatManager;
040
041import org.jxmpp.jid.parts.Resourcepart;
042
043/**
044 * Autojoin bookmarked Multi-User Chat conferences.
045 *
046 * @see <a href="http://xmpp.org/extensions/xep-0048.html">XEP-48: Bookmarks</a>
047 *
048 */
049public final class MucBookmarkAutojoinManager extends Manager {
050
051    private static final Logger LOGGER = Logger.getLogger(MucBookmarkAutojoinManager.class.getName());
052
053    private static final Map<XMPPConnection, MucBookmarkAutojoinManager> INSTANCES = new WeakHashMap<>();
054
055    private static boolean autojoinEnabledDefault = false;
056
057    static {
058        XMPPConnectionRegistry.addConnectionCreationListener(new ConnectionCreationListener() {
059            @Override
060            public void connectionCreated(XMPPConnection connection) {
061                getInstanceFor(connection);
062            }
063        });
064    }
065
066    public static void setAutojoinPerDefault(boolean autojoin) {
067        autojoinEnabledDefault = autojoin;
068    }
069
070    public static synchronized MucBookmarkAutojoinManager getInstanceFor(XMPPConnection connection) {
071        MucBookmarkAutojoinManager mbam = INSTANCES.get(connection);
072        if (mbam == null) {
073            mbam = new MucBookmarkAutojoinManager(connection);
074            INSTANCES.put(connection, mbam);
075        }
076        return mbam;
077    }
078
079    private final MultiUserChatManager multiUserChatManager;
080    private final BookmarkManager bookmarkManager;
081
082    private boolean autojoinEnabled = autojoinEnabledDefault;
083
084    private MucBookmarkAutojoinManager(XMPPConnection connection) {
085        super(connection);
086        multiUserChatManager = MultiUserChatManager.getInstanceFor(connection);
087        bookmarkManager = BookmarkManager.getBookmarkManager(connection);
088        connection.addConnectionListener(new ConnectionListener() {
089            @Override
090            public void authenticated(XMPPConnection connection, boolean resumed) {
091                if (!autojoinEnabled) {
092                    return;
093                }
094                // TODO handle resumed case?
095                autojoinBookmarkedConferences();
096            }
097        });
098    }
099
100    public void setAutojoinEnabled(boolean autojoin) {
101        autojoinEnabled = autojoin;
102    }
103
104    public void autojoinBookmarkedConferences() {
105        List<BookmarkedConference> bookmarkedConferences;
106        try {
107            bookmarkedConferences = bookmarkManager.getBookmarkedConferences();
108        }
109        catch (NotConnectedException | InterruptedException e) {
110            LOGGER.log(Level.FINER, "Could not get MUC bookmarks", e);
111            return;
112        }
113        catch (NoResponseException | XMPPErrorException e) {
114            LOGGER.log(Level.WARNING, "Could not get MUC bookmarks", e);
115            return;
116        }
117
118        final XMPPConnection connection = connection();
119        Resourcepart defaultNick = connection.getUser().getResourcepart();
120
121        for (BookmarkedConference bookmarkedConference : bookmarkedConferences) {
122            if (!bookmarkedConference.isAutoJoin()) {
123                continue;
124            }
125            Resourcepart nick = bookmarkedConference.getNickname();
126            if (nick == null) {
127                nick = defaultNick;
128            }
129            String password = bookmarkedConference.getPassword();
130            MultiUserChat muc = multiUserChatManager.getMultiUserChat(bookmarkedConference.getJid());
131            try {
132                MucCreateConfigFormHandle handle = muc.createOrJoinIfNecessary(nick, password);
133                if (handle != null) {
134                    handle.makeInstant();
135                }
136            }
137            catch (NotConnectedException | InterruptedException e) {
138                LOGGER.log(Level.FINER, "Could not autojoin bookmarked MUC", e);
139                // abort here
140                break;
141            }
142            catch (NotAMucServiceException | NoResponseException | XMPPErrorException e) {
143                // Do no abort, just log,
144                LOGGER.log(Level.WARNING, "Could not autojoin bookmarked MUC", e);
145            }
146        }
147    }
148}