/** * $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; } } }