Shuyi Chen | d7955ce | 2013-05-22 14:51:55 -0700 | [diff] [blame] | 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 | */ |
| 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 | */ |
| 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 | */ |
| 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 | */ |
| 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 | */ |
| 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 | */ |
| 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 | */ |
| 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 | */ |
| 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 | |
| 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 | } |