BookmarkManager.java

  1. /**
  2.  *
  3.  * Copyright 2003-2007 Jive Software.
  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.bookmarks;

  18. import java.util.Collections;
  19. import java.util.Iterator;
  20. import java.util.List;
  21. import java.util.Map;
  22. import java.util.WeakHashMap;

  23. import org.jivesoftware.smack.SmackException;
  24. import org.jivesoftware.smack.SmackException.NoResponseException;
  25. import org.jivesoftware.smack.SmackException.NotConnectedException;
  26. import org.jivesoftware.smack.XMPPConnection;
  27. import org.jivesoftware.smack.XMPPException;
  28. import org.jivesoftware.smack.XMPPException.XMPPErrorException;
  29. import org.jivesoftware.smackx.iqprivate.PrivateDataManager;


  30. /**
  31.  * Provides methods to manage bookmarks in accordance with XEP-0048. Methods for managing URLs and
  32.  * Conferences are provided.
  33.  * </p>
  34.  * It should be noted that some extensions have been made to the XEP. There is an attribute on URLs
  35.  * that marks a url as a news feed and also a sub-element can be added to either a URL or conference
  36.  * indicated that it is shared amongst all users on a server.
  37.  *
  38.  * @author Alexander Wenckus
  39.  */
  40. public class BookmarkManager {
  41.     private static final Map<XMPPConnection, BookmarkManager> bookmarkManagerMap = new WeakHashMap<XMPPConnection, BookmarkManager>();

  42.     static {
  43.         PrivateDataManager.addPrivateDataProvider("storage", "storage:bookmarks",
  44.                 new Bookmarks.Provider());
  45.     }

  46.     /**
  47.      * Returns the <i>BookmarkManager</i> for a connection, if it doesn't exist it is created.
  48.      *
  49.      * @param connection the connection for which the manager is desired.
  50.      * @return Returns the <i>BookmarkManager</i> for a connection, if it doesn't
  51.      * exist it is created.
  52.      * @throws XMPPException
  53.      * @throws SmackException thrown has not been authenticated.
  54.      * @throws IllegalArgumentException when the connection is null.
  55.      */
  56.     public synchronized static BookmarkManager getBookmarkManager(XMPPConnection connection)
  57.                     throws XMPPException, SmackException
  58.     {
  59.         BookmarkManager manager = (BookmarkManager) bookmarkManagerMap.get(connection);
  60.         if (manager == null) {
  61.             manager = new BookmarkManager(connection);
  62.         }
  63.         return manager;
  64.     }

  65.     private PrivateDataManager privateDataManager;
  66.     private Bookmarks bookmarks;
  67.     private final Object bookmarkLock = new Object();

  68.     /**
  69.      * Default constructor. Registers the data provider with the private data manager in the
  70.      * storage:bookmarks namespace.
  71.      *
  72.      * @param connection the connection for persisting and retrieving bookmarks.
  73.      */
  74.     private BookmarkManager(XMPPConnection connection) throws XMPPException, SmackException {
  75.         privateDataManager = PrivateDataManager.getInstanceFor(connection);
  76.         bookmarkManagerMap.put(connection, this);
  77.     }

  78.     /**
  79.      * Returns all currently bookmarked conferences.
  80.      *
  81.      * @return returns all currently bookmarked conferences
  82.      * @throws XMPPErrorException
  83.      * @throws NoResponseException
  84.      * @throws NotConnectedException
  85.      * @throws InterruptedException
  86.      * @see BookmarkedConference
  87.      */
  88.     public List<BookmarkedConference> getBookmarkedConferences() throws NoResponseException, XMPPErrorException, NotConnectedException, InterruptedException {
  89.         retrieveBookmarks();
  90.         return Collections.unmodifiableList(bookmarks.getBookmarkedConferences());
  91.     }

  92.     /**
  93.      * Adds or updates a conference in the bookmarks.
  94.      *
  95.      * @param name the name of the conference
  96.      * @param jid the jid of the conference
  97.      * @param isAutoJoin whether or not to join this conference automatically on login
  98.      * @param nickname the nickname to use for the user when joining the conference
  99.      * @param password the password to use for the user when joining the conference
  100.      * @throws XMPPErrorException thrown when there is an issue retrieving the current bookmarks from
  101.      * the server.
  102.      * @throws NoResponseException if there was no response from the server.
  103.      * @throws NotConnectedException
  104.      * @throws InterruptedException
  105.      */
  106.     public void addBookmarkedConference(String name, String jid, boolean isAutoJoin,
  107.             String nickname, String password) throws NoResponseException, XMPPErrorException, NotConnectedException, InterruptedException
  108.     {
  109.         retrieveBookmarks();
  110.         BookmarkedConference bookmark
  111.                 = new BookmarkedConference(name, jid, isAutoJoin, nickname, password);
  112.         List<BookmarkedConference> conferences = bookmarks.getBookmarkedConferences();
  113.         if(conferences.contains(bookmark)) {
  114.             BookmarkedConference oldConference = conferences.get(conferences.indexOf(bookmark));
  115.             if(oldConference.isShared()) {
  116.                 throw new IllegalArgumentException("Cannot modify shared bookmark");
  117.             }
  118.             oldConference.setAutoJoin(isAutoJoin);
  119.             oldConference.setName(name);
  120.             oldConference.setNickname(nickname);
  121.             oldConference.setPassword(password);
  122.         }
  123.         else {
  124.             bookmarks.addBookmarkedConference(bookmark);
  125.         }
  126.         privateDataManager.setPrivateData(bookmarks);
  127.     }

  128.     /**
  129.      * Removes a conference from the bookmarks.
  130.      *
  131.      * @param jid the jid of the conference to be removed.
  132.      * @throws XMPPErrorException thrown when there is a problem with the connection attempting to
  133.      * retrieve the bookmarks or persist the bookmarks.
  134.      * @throws NoResponseException if there was no response from the server.
  135.      * @throws NotConnectedException
  136.      * @throws InterruptedException
  137.      * @throws IllegalArgumentException thrown when the conference being removed is a shared
  138.      * conference
  139.      */
  140.     public void removeBookmarkedConference(String jid) throws NoResponseException, XMPPErrorException, NotConnectedException, InterruptedException {
  141.         retrieveBookmarks();
  142.         Iterator<BookmarkedConference> it = bookmarks.getBookmarkedConferences().iterator();
  143.         while(it.hasNext()) {
  144.             BookmarkedConference conference = it.next();
  145.             if(conference.getJid().equalsIgnoreCase(jid)) {
  146.                 if(conference.isShared()) {
  147.                     throw new IllegalArgumentException("Conference is shared and can't be removed");
  148.                 }
  149.                 it.remove();
  150.                 privateDataManager.setPrivateData(bookmarks);
  151.                 return;
  152.             }
  153.         }
  154.     }

  155.     /**
  156.      * Returns an unmodifiable collection of all bookmarked urls.
  157.      *
  158.      * @return returns an unmodifiable collection of all bookmarked urls.
  159.      * @throws XMPPErrorException thrown when there is a problem retriving bookmarks from the server.
  160.      * @throws NoResponseException if there was no response from the server.
  161.      * @throws NotConnectedException
  162.      * @throws InterruptedException
  163.      */
  164.     public List<BookmarkedURL> getBookmarkedURLs() throws NoResponseException, XMPPErrorException, NotConnectedException, InterruptedException {
  165.         retrieveBookmarks();
  166.         return Collections.unmodifiableList(bookmarks.getBookmarkedURLS());
  167.     }

  168.     /**
  169.      * Adds a new url or updates an already existing url in the bookmarks.
  170.      *
  171.      * @param URL the url of the bookmark
  172.      * @param name the name of the bookmark
  173.      * @param isRSS whether or not the url is an rss feed
  174.      * @throws XMPPErrorException thrown when there is an error retriving or saving bookmarks from or to
  175.      * the server
  176.      * @throws NoResponseException if there was no response from the server.
  177.      * @throws NotConnectedException
  178.      * @throws InterruptedException
  179.      */
  180.     public void addBookmarkedURL(String URL, String name, boolean isRSS) throws NoResponseException, XMPPErrorException, NotConnectedException, InterruptedException {
  181.         retrieveBookmarks();
  182.         BookmarkedURL bookmark = new BookmarkedURL(URL, name, isRSS);
  183.         List<BookmarkedURL> urls = bookmarks.getBookmarkedURLS();
  184.         if(urls.contains(bookmark)) {
  185.             BookmarkedURL oldURL = urls.get(urls.indexOf(bookmark));
  186.             if(oldURL.isShared()) {
  187.                 throw new IllegalArgumentException("Cannot modify shared bookmarks");
  188.             }
  189.             oldURL.setName(name);
  190.             oldURL.setRss(isRSS);
  191.         }
  192.         else {
  193.             bookmarks.addBookmarkedURL(bookmark);
  194.         }
  195.         privateDataManager.setPrivateData(bookmarks);
  196.     }

  197.     /**
  198.      *  Removes a url from the bookmarks.
  199.      *
  200.      * @param bookmarkURL the url of the bookmark to remove
  201.      * @throws XMPPErrorException thrown if there is an error retriving or saving bookmarks from or to
  202.      * the server.
  203.      * @throws NoResponseException if there was no response from the server.
  204.      * @throws NotConnectedException
  205.      * @throws InterruptedException
  206.      */
  207.     public void removeBookmarkedURL(String bookmarkURL) throws NoResponseException, XMPPErrorException, NotConnectedException, InterruptedException {
  208.         retrieveBookmarks();
  209.         Iterator<BookmarkedURL> it = bookmarks.getBookmarkedURLS().iterator();
  210.         while(it.hasNext()) {
  211.             BookmarkedURL bookmark = it.next();
  212.             if(bookmark.getURL().equalsIgnoreCase(bookmarkURL)) {
  213.                 if(bookmark.isShared()) {
  214.                     throw new IllegalArgumentException("Cannot delete a shared bookmark.");
  215.                 }
  216.                 it.remove();
  217.                 privateDataManager.setPrivateData(bookmarks);
  218.                 return;
  219.             }
  220.         }
  221.     }

  222.     private Bookmarks retrieveBookmarks() throws NoResponseException, XMPPErrorException, NotConnectedException, InterruptedException {
  223.         synchronized(bookmarkLock) {
  224.             if(bookmarks == null) {
  225.                 bookmarks = (Bookmarks) privateDataManager.getPrivateData("storage",
  226.                         "storage:bookmarks");
  227.             }
  228.             return bookmarks;
  229.         }
  230.     }
  231. }