1 /** 2 * $Revision$ 3 * $Date$ 4 * 5 * Copyright 2003-2007 Jive Software. 6 * 7 * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License"); 8 * you may not use this file except in compliance with the License. 9 * You may obtain a copy of the License at 10 * 11 * http://www.apache.org/licenses/LICENSE-2.0 12 * 13 * Unless required by applicable law or agreed to in writing, software 14 * distributed under the License is distributed on an "AS IS" BASIS, 15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 * See the License for the specific language governing permissions and 17 * limitations under the License. 18 */ 19 20 package org.jivesoftware.smackx.bookmark; 21 22 import org.jivesoftware.smack.Connection; 23 import org.jivesoftware.smack.XMPPException; 24 import org.jivesoftware.smackx.PrivateDataManager; 25 26 import java.util.*; 27 28 /** 29 * Provides methods to manage bookmarks in accordance with JEP-0048. Methods for managing URLs and 30 * Conferences are provided. 31 * </p> 32 * It should be noted that some extensions have been made to the JEP. There is an attribute on URLs 33 * that marks a url as a news feed and also a sub-element can be added to either a URL or conference 34 * indicated that it is shared amongst all users on a server. 35 * 36 * @author Alexander Wenckus 37 */ 38 public class BookmarkManager { 39 private static final Map<Connection, BookmarkManager> bookmarkManagerMap = new HashMap<Connection, BookmarkManager>(); 40 static { 41 PrivateDataManager.addPrivateDataProvider("storage", "storage:bookmarks", 42 new Bookmarks.Provider()); 43 } 44 45 /** 46 * Returns the <i>BookmarkManager</i> for a connection, if it doesn't exist it is created. 47 * 48 * @param connection the connection for which the manager is desired. 49 * @return Returns the <i>BookmarkManager</i> for a connection, if it doesn't 50 * exist it is created. 51 * @throws XMPPException Thrown if the connection is null or has not yet been authenticated. 52 */ getBookmarkManager(Connection connection)53 public synchronized static BookmarkManager getBookmarkManager(Connection connection) 54 throws XMPPException 55 { 56 BookmarkManager manager = (BookmarkManager) bookmarkManagerMap.get(connection); 57 if(manager == null) { 58 manager = new BookmarkManager(connection); 59 bookmarkManagerMap.put(connection, manager); 60 } 61 return manager; 62 } 63 64 private PrivateDataManager privateDataManager; 65 private Bookmarks bookmarks; 66 private final Object bookmarkLock = new Object(); 67 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 * @throws XMPPException thrown when the connection is null or has not been authenticated. 74 */ BookmarkManager(Connection connection)75 private BookmarkManager(Connection connection) throws XMPPException { 76 if(connection == null || !connection.isAuthenticated()) { 77 throw new XMPPException("Invalid connection."); 78 } 79 this.privateDataManager = new PrivateDataManager(connection); 80 } 81 82 /** 83 * Returns all currently bookmarked conferences. 84 * 85 * @return returns all currently bookmarked conferences 86 * @throws XMPPException thrown when there was an error retrieving the current bookmarks from 87 * the server. 88 * @see BookmarkedConference 89 */ getBookmarkedConferences()90 public Collection<BookmarkedConference> getBookmarkedConferences() throws XMPPException { 91 retrieveBookmarks(); 92 return Collections.unmodifiableCollection(bookmarks.getBookmarkedConferences()); 93 } 94 95 /** 96 * Adds or updates a conference in the bookmarks. 97 * 98 * @param name the name of the conference 99 * @param jid the jid of the conference 100 * @param isAutoJoin whether or not to join this conference automatically on login 101 * @param nickname the nickname to use for the user when joining the conference 102 * @param password the password to use for the user when joining the conference 103 * @throws XMPPException thrown when there is an issue retrieving the current bookmarks from 104 * the server. 105 */ addBookmarkedConference(String name, String jid, boolean isAutoJoin, String nickname, String password)106 public void addBookmarkedConference(String name, String jid, boolean isAutoJoin, 107 String nickname, String password) throws XMPPException 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 /** 130 * Removes a conference from the bookmarks. 131 * 132 * @param jid the jid of the conference to be removed. 133 * @throws XMPPException thrown when there is a problem with the connection attempting to 134 * retrieve the bookmarks or persist the bookmarks. 135 * @throws IllegalArgumentException thrown when the conference being removed is a shared 136 * conference 137 */ removeBookmarkedConference(String jid)138 public void removeBookmarkedConference(String jid) throws XMPPException { 139 retrieveBookmarks(); 140 Iterator<BookmarkedConference> it = bookmarks.getBookmarkedConferences().iterator(); 141 while(it.hasNext()) { 142 BookmarkedConference conference = it.next(); 143 if(conference.getJid().equalsIgnoreCase(jid)) { 144 if(conference.isShared()) { 145 throw new IllegalArgumentException("Conference is shared and can't be removed"); 146 } 147 it.remove(); 148 privateDataManager.setPrivateData(bookmarks); 149 return; 150 } 151 } 152 } 153 154 /** 155 * Returns an unmodifiable collection of all bookmarked urls. 156 * 157 * @return returns an unmodifiable collection of all bookmarked urls. 158 * @throws XMPPException thrown when there is a problem retriving bookmarks from the server. 159 */ getBookmarkedURLs()160 public Collection<BookmarkedURL> getBookmarkedURLs() throws XMPPException { 161 retrieveBookmarks(); 162 return Collections.unmodifiableCollection(bookmarks.getBookmarkedURLS()); 163 } 164 165 /** 166 * Adds a new url or updates an already existing url in the bookmarks. 167 * 168 * @param URL the url of the bookmark 169 * @param name the name of the bookmark 170 * @param isRSS whether or not the url is an rss feed 171 * @throws XMPPException thrown when there is an error retriving or saving bookmarks from or to 172 * the server 173 */ addBookmarkedURL(String URL, String name, boolean isRSS)174 public void addBookmarkedURL(String URL, String name, boolean isRSS) throws XMPPException { 175 retrieveBookmarks(); 176 BookmarkedURL bookmark = new BookmarkedURL(URL, name, isRSS); 177 List<BookmarkedURL> urls = bookmarks.getBookmarkedURLS(); 178 if(urls.contains(bookmark)) { 179 BookmarkedURL oldURL = urls.get(urls.indexOf(bookmark)); 180 if(oldURL.isShared()) { 181 throw new IllegalArgumentException("Cannot modify shared bookmarks"); 182 } 183 oldURL.setName(name); 184 oldURL.setRss(isRSS); 185 } 186 else { 187 bookmarks.addBookmarkedURL(bookmark); 188 } 189 privateDataManager.setPrivateData(bookmarks); 190 } 191 192 /** 193 * Removes a url from the bookmarks. 194 * 195 * @param bookmarkURL the url of the bookmark to remove 196 * @throws XMPPException thrown if there is an error retriving or saving bookmarks from or to 197 * the server. 198 */ removeBookmarkedURL(String bookmarkURL)199 public void removeBookmarkedURL(String bookmarkURL) throws XMPPException { 200 retrieveBookmarks(); 201 Iterator<BookmarkedURL> it = bookmarks.getBookmarkedURLS().iterator(); 202 while(it.hasNext()) { 203 BookmarkedURL bookmark = it.next(); 204 if(bookmark.getURL().equalsIgnoreCase(bookmarkURL)) { 205 if(bookmark.isShared()) { 206 throw new IllegalArgumentException("Cannot delete a shared bookmark."); 207 } 208 it.remove(); 209 privateDataManager.setPrivateData(bookmarks); 210 return; 211 } 212 } 213 } 214 retrieveBookmarks()215 private Bookmarks retrieveBookmarks() throws XMPPException { 216 synchronized(bookmarkLock) { 217 if(bookmarks == null) { 218 bookmarks = (Bookmarks) privateDataManager.getPrivateData("storage", 219 "storage:bookmarks"); 220 } 221 return bookmarks; 222 } 223 } 224 } 225