/**
* $Revision$
* $Date$
*
* Copyright 2003-2007 Jive Software.
*
* All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jivesoftware.smackx.bookmark;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import org.jivesoftware.smack.Connection;
import org.jivesoftware.smack.XMPPException;
import org.jivesoftware.smackx.PrivateDataManager;
/**
* Provides methods to manage bookmarks in accordance with JEP-0048. Methods for
* managing URLs and Conferences are provided. </p> It should be noted that some
* extensions have been made to the JEP. There is an attribute on URLs that
* marks a url as a news feed and also a sub-element can be added to either a
* URL or conference indicated that it is shared amongst all users on a server.
*
* @author Alexander Wenckus
*/
public class BookmarkManager {
private static final Map<Connection, BookmarkManager> bookmarkManagerMap = new HashMap<Connection, BookmarkManager>();
static {
PrivateDataManager.addPrivateDataProvider("storage",
"storage:bookmarks", new Bookmarks.Provider());
}
/**
* Returns the <i>BookmarkManager</i> for a connection, if it doesn't exist
* it is created.
*
* @param connection
* the connection for which the manager is desired.
* @return Returns the <i>BookmarkManager</i> for a connection, if it
* doesn't exist it is created.
* @throws XMPPException
* Thrown if the connection is null or has not yet been
* authenticated.
*/
public synchronized static BookmarkManager getBookmarkManager(
Connection connection) throws XMPPException {
BookmarkManager manager = bookmarkManagerMap.get(connection);
if (manager == null) {
manager = new BookmarkManager(connection);
bookmarkManagerMap.put(connection, manager);
}
return manager;
}
private final PrivateDataManager privateDataManager;
private Bookmarks bookmarks;
private final Object bookmarkLock = new Object();
/**
* Default constructor. Registers the data provider with the private data
* manager in the storage:bookmarks namespace.
*
* @param connection
* the connection for persisting and retrieving bookmarks.
* @throws XMPPException
* thrown when the connection is null or has not been
* authenticated.
*/
private BookmarkManager(Connection connection) throws XMPPException {
if (connection == null || !connection.isAuthenticated()) {
throw new XMPPException("Invalid connection.");
}
privateDataManager = new PrivateDataManager(connection);
}
/**
* Adds or updates a conference in the bookmarks.
*
* @param name
* the name of the conference
* @param jid
* the jid of the conference
* @param isAutoJoin
* whether or not to join this conference automatically on login
* @param nickname
* the nickname to use for the user when joining the conference
* @param password
* the password to use for the user when joining the conference
* @throws XMPPException
* thrown when there is an issue retrieving the current
* bookmarks from the server.
*/
public void addBookmarkedConference(String name, String jid,
boolean isAutoJoin, String nickname, String password)
throws XMPPException {
retrieveBookmarks();
final BookmarkedConference bookmark = new BookmarkedConference(name,
jid, isAutoJoin, nickname, password);
final List<BookmarkedConference> conferences = bookmarks
.getBookmarkedConferences();
if (conferences.contains(bookmark)) {
final BookmarkedConference oldConference = conferences
.get(conferences.indexOf(bookmark));
if (oldConference.isShared()) {
throw new IllegalArgumentException(
"Cannot modify shared bookmark");
}
oldConference.setAutoJoin(isAutoJoin);
oldConference.setName(name);
oldConference.setNickname(nickname);
oldConference.setPassword(password);
} else {
bookmarks.addBookmarkedConference(bookmark);
}
privateDataManager.setPrivateData(bookmarks);
}
/**
* Adds a new url or updates an already existing url in the bookmarks.
*
* @param URL
* the url of the bookmark
* @param name
* the name of the bookmark
* @param isRSS
* whether or not the url is an rss feed
* @throws XMPPException
* thrown when there is an error retriving or saving bookmarks
* from or to the server
*/
public void addBookmarkedURL(String URL, String name, boolean isRSS)
throws XMPPException {
retrieveBookmarks();
final BookmarkedURL bookmark = new BookmarkedURL(URL, name, isRSS);
final List<BookmarkedURL> urls = bookmarks.getBookmarkedURLS();
if (urls.contains(bookmark)) {
final BookmarkedURL oldURL = urls.get(urls.indexOf(bookmark));
if (oldURL.isShared()) {
throw new IllegalArgumentException(
"Cannot modify shared bookmarks");
}
oldURL.setName(name);
oldURL.setRss(isRSS);
} else {
bookmarks.addBookmarkedURL(bookmark);
}
privateDataManager.setPrivateData(bookmarks);
}
/**
* Returns all currently bookmarked conferences.
*
* @return returns all currently bookmarked conferences
* @throws XMPPException
* thrown when there was an error retrieving the current
* bookmarks from the server.
* @see BookmarkedConference
*/
public Collection<BookmarkedConference> getBookmarkedConferences()
throws XMPPException {
retrieveBookmarks();
return Collections.unmodifiableCollection(bookmarks
.getBookmarkedConferences());
}
/**
* Returns an unmodifiable collection of all bookmarked urls.
*
* @return returns an unmodifiable collection of all bookmarked urls.
* @throws XMPPException
* thrown when there is a problem retriving bookmarks from the
* server.
*/
public Collection<BookmarkedURL> getBookmarkedURLs() throws XMPPException {
retrieveBookmarks();
return Collections
.unmodifiableCollection(bookmarks.getBookmarkedURLS());
}
/**
* Removes a conference from the bookmarks.
*
* @param jid
* the jid of the conference to be removed.
* @throws XMPPException
* thrown when there is a problem with the connection attempting
* to retrieve the bookmarks or persist the bookmarks.
* @throws IllegalArgumentException
* thrown when the conference being removed is a shared
* conference
*/
public void removeBookmarkedConference(String jid) throws XMPPException {
retrieveBookmarks();
final Iterator<BookmarkedConference> it = bookmarks
.getBookmarkedConferences().iterator();
while (it.hasNext()) {
final BookmarkedConference conference = it.next();
if (conference.getJid().equalsIgnoreCase(jid)) {
if (conference.isShared()) {
throw new IllegalArgumentException(
"Conference is shared and can't be removed");
}
it.remove();
privateDataManager.setPrivateData(bookmarks);
return;
}
}
}
/**
* Removes a url from the bookmarks.
*
* @param bookmarkURL
* the url of the bookmark to remove
* @throws XMPPException
* thrown if there is an error retriving or saving bookmarks
* from or to the server.
*/
public void removeBookmarkedURL(String bookmarkURL) throws XMPPException {
retrieveBookmarks();
final Iterator<BookmarkedURL> it = bookmarks.getBookmarkedURLS()
.iterator();
while (it.hasNext()) {
final BookmarkedURL bookmark = it.next();
if (bookmark.getURL().equalsIgnoreCase(bookmarkURL)) {
if (bookmark.isShared()) {
throw new IllegalArgumentException(
"Cannot delete a shared bookmark.");
}
it.remove();
privateDataManager.setPrivateData(bookmarks);
return;
}
}
}
private Bookmarks retrieveBookmarks() throws XMPPException {
synchronized (bookmarkLock) {
if (bookmarks == null) {
bookmarks = (Bookmarks) privateDataManager.getPrivateData(
"storage", "storage:bookmarks");
}
return bookmarks;
}
}
}