BookmarkManager.java

  1package eu.siacs.conversations.xmpp.manager;
  2
  3import android.util.Log;
  4import androidx.annotation.NonNull;
  5import com.google.common.collect.ImmutableMap;
  6import com.google.common.util.concurrent.FutureCallback;
  7import com.google.common.util.concurrent.Futures;
  8import com.google.common.util.concurrent.ListenableFuture;
  9import com.google.common.util.concurrent.MoreExecutors;
 10import eu.siacs.conversations.Config;
 11import eu.siacs.conversations.entities.Bookmark;
 12import eu.siacs.conversations.services.XmppConnectionService;
 13import eu.siacs.conversations.xml.Namespace;
 14import eu.siacs.conversations.xmpp.Jid;
 15import eu.siacs.conversations.xmpp.XmppConnection;
 16import im.conversations.android.xmpp.NodeConfiguration;
 17import im.conversations.android.xmpp.model.bookmark2.Conference;
 18import im.conversations.android.xmpp.model.bookmark2.Nick;
 19import im.conversations.android.xmpp.model.pubsub.Items;
 20import im.conversations.android.xmpp.model.pubsub.event.Retract;
 21import java.util.Collection;
 22import java.util.Collections;
 23import java.util.Map;
 24
 25public class BookmarkManager extends AbstractBookmarkManager {
 26
 27    public BookmarkManager(final XmppConnectionService service, XmppConnection connection) {
 28        super(service, connection);
 29    }
 30
 31    public void fetch() {
 32        final var future = getManager(PepManager.class).fetchItems(Conference.class);
 33        Futures.addCallback(
 34                future,
 35                new FutureCallback<>() {
 36                    @Override
 37                    public void onSuccess(final Map<String, Conference> bookmarks) {
 38                        final var builder = new ImmutableMap.Builder<Jid, Bookmark>();
 39                        for (final var entry : bookmarks.entrySet()) {
 40                            final Bookmark bookmark =
 41                                    Bookmark.parseFromItem(
 42                                            entry.getKey(), entry.getValue(), getAccount());
 43                            if (bookmark == null) {
 44                                continue;
 45                            }
 46                            builder.put(bookmark.getJid(), bookmark);
 47                        }
 48                        processBookmarksInitial(builder.buildKeepingLast(), true);
 49                    }
 50
 51                    @Override
 52                    public void onFailure(@NonNull final Throwable throwable) {
 53                        Log.d(Config.LOGTAG, "Could not fetch bookmarks", throwable);
 54                    }
 55                },
 56                MoreExecutors.directExecutor());
 57    }
 58
 59    public void handleItems(final Items items) {
 60        this.handleItems(items.getItemMap(Conference.class));
 61        this.handleRetractions(items.getRetractions());
 62    }
 63
 64    private void handleRetractions(final Collection<Retract> retractions) {
 65        final var account = getAccount();
 66        for (final var retract : retractions) {
 67            final Jid id = Jid.Invalid.getNullForInvalid(retract.getAttributeAsJid("id"));
 68            if (id != null) {
 69                account.removeBookmark(id);
 70                Log.d(Config.LOGTAG, account.getJid().asBareJid() + ": deleted bookmark for " + id);
 71                processDeletedBookmark(id);
 72                service.updateConversationUi();
 73            }
 74        }
 75    }
 76
 77    private void handleItems(final Map<String, Conference> items) {
 78        final var account = getAccount();
 79        for (final var item : items.entrySet()) {
 80            // TODO parseFromItem can be included in this Manager
 81            final Bookmark bookmark =
 82                    Bookmark.parseFromItem(item.getKey(), item.getValue(), account);
 83            if (bookmark == null) {
 84                continue;
 85            }
 86            account.putBookmark(bookmark);
 87            service.processModifiedBookmark(bookmark);
 88            service.updateConversationUi();
 89        }
 90    }
 91
 92    public ListenableFuture<Void> publishBookmark(final Jid address, final boolean autoJoin) {
 93        return publishBookmark(address, autoJoin, null);
 94    }
 95
 96    public ListenableFuture<Void> publishBookmark(
 97            final Jid address, final boolean autoJoin, final String nick) {
 98        final var itemId = address.toString();
 99        final var conference = new Conference();
100        conference.setAutoJoin(autoJoin);
101        if (nick != null) {
102            conference.addExtension(new Nick()).setContent(nick);
103        }
104        return Futures.transform(
105                getManager(PepManager.class)
106                        .publish(conference, itemId, NodeConfiguration.WHITELIST_MAX_ITEMS),
107                result -> null,
108                MoreExecutors.directExecutor());
109    }
110
111    public ListenableFuture<Void> retractBookmark(final Jid address) {
112        final var itemId = address.toString();
113        return Futures.transform(
114                getManager(PepManager.class).retract(itemId, Namespace.BOOKMARKS2),
115                result -> null,
116                MoreExecutors.directExecutor());
117    }
118
119    private void deleteAllItems() {
120        final var account = getAccount();
121        final var previous = account.getBookmarkedJids();
122        account.setBookmarks(Collections.emptyMap());
123        processDeletedBookmarks(previous);
124    }
125
126    public void handleDelete() {
127        Log.d(Config.LOGTAG, getAccount().getJid().asBareJid() + ": deleted bookmarks node");
128        this.deleteAllItems();
129    }
130
131    public void handlePurge() {
132        Log.d(Config.LOGTAG, getAccount().getJid().asBareJid() + ": purged bookmarks");
133        this.deleteAllItems();
134    }
135}