/** * $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 org.jivesoftware.smack.Connection; import org.jivesoftware.smack.XMPPException; import org.jivesoftware.smackx.PrivateDataManager; import java.util.*; /** * 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 = (BookmarkManager) bookmarkManagerMap.get(connection); if(manager == null) { manager = new BookmarkManager(connection); bookmarkManagerMap.put(connection, manager); } return manager; } private 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."); } this.privateDataManager = new PrivateDataManager(connection); } /** * 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()); } /** * 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(); BookmarkedConference bookmark = new BookmarkedConference(name, jid, isAutoJoin, nickname, password); List<BookmarkedConference> conferences = bookmarks.getBookmarkedConferences(); if(conferences.contains(bookmark)) { 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); } /** * 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(); Iterator<BookmarkedConference> it = bookmarks.getBookmarkedConferences().iterator(); while(it.hasNext()) { 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; } } } /** * 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()); } /** * 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(); BookmarkedURL bookmark = new BookmarkedURL(URL, name, isRSS); List<BookmarkedURL> urls = bookmarks.getBookmarkedURLS(); if(urls.contains(bookmark)) { 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); } /** * 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(); Iterator<BookmarkedURL> it = bookmarks.getBookmarkedURLS().iterator(); while(it.hasNext()) { 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; } } }