diff --git a/source/org/jivesoftware/smackx/bookmark/BookmarkManager.java b/source/org/jivesoftware/smackx/bookmark/BookmarkManager.java new file mode 100644 index 000000000..f9127b84c --- /dev/null +++ b/source/org/jivesoftware/smackx/bookmark/BookmarkManager.java @@ -0,0 +1,214 @@ +/** + * $RCSfile: $ + * $Revision: $ + * $Date: $ + * + * Copyright (C) 2006 Jive Software. All rights reserved. + * This software is the proprietary information of Jive Software. Use is subject to license terms. + */ +package org.jivesoftware.smackx.bookmark; + +import org.jivesoftware.smack.XMPPConnection; +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. + *
+ * 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 bookmarkManagerMap = new HashMap(); + static { + PrivateDataManager.addPrivateDataProvider("storage", "storage:bookmarks", + new Bookmarks.Provider()); + } + + /** + * Returns the BookmarkManager for a connection, if it doesn't exist it is created. + * + * @param connection the connection for which the manager is desired. + * @return Returns the BookmarkManager 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(XMPPConnection 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(XMPPConnection 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 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 conferences = bookmarks.getBookmarkedConferences(); + if(conferences.contains(bookmark)) { + BookmarkedConference oldConference = (BookmarkedConference) + 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 it = bookmarks.getBookmarkedConferences().iterator(); + while(it.hasNext()) { + BookmarkedConference conference = (BookmarkedConference) 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 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 urls = bookmarks.getBookmarkedURLS(); + if(urls.contains(bookmark)) { + BookmarkedURL oldURL = (BookmarkedURL) 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 it = bookmarks.getBookmarkedURLS().iterator(); + while(it.hasNext()) { + BookmarkedURL bookmark = (BookmarkedURL) 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; + } + } +} diff --git a/source/org/jivesoftware/smackx/bookmark/BookmarkedConference.java b/source/org/jivesoftware/smackx/bookmark/BookmarkedConference.java index 3067405ea..d827b4a1f 100644 --- a/source/org/jivesoftware/smackx/bookmark/BookmarkedConference.java +++ b/source/org/jivesoftware/smackx/bookmark/BookmarkedConference.java @@ -12,14 +12,29 @@ package org.jivesoftware.smackx.bookmark; * * @author Derek DeMoro */ -public class BookmarkedConference { +public class BookmarkedConference implements SharedBookmark { private String name; private boolean autoJoin; - private String jid; + private final String jid; private String nickname; private String password; + private boolean isShared; + + protected BookmarkedConference(String jid) { + this.jid = jid; + } + + protected BookmarkedConference(String name, String jid, boolean autoJoin, String nickname, + String password) + { + this.name = name; + this.jid = jid; + this.autoJoin = autoJoin; + this.nickname = nickname; + this.password = password; + } /** @@ -31,7 +46,7 @@ public class BookmarkedConference { return name; } - public void setName(String name) { + protected void setName(String name) { this.name = name; } @@ -44,7 +59,7 @@ public class BookmarkedConference { return autoJoin; } - public void setAutoJoin(boolean autoJoin) { + protected void setAutoJoin(boolean autoJoin) { this.autoJoin = autoJoin; } @@ -57,10 +72,6 @@ public class BookmarkedConference { return jid; } - public void setJid(String jid) { - this.jid = jid; - } - /** * Returns the nickname to use when joining this conference room. This is an optional * value and may return null. @@ -71,7 +82,7 @@ public class BookmarkedConference { return nickname; } - public void setNickname(String nickname) { + protected void setNickname(String nickname) { this.nickname = nickname; } @@ -85,7 +96,23 @@ public class BookmarkedConference { return password; } - public void setPassword(String password) { + protected void setPassword(String password) { this.password = password; } + + public boolean equals(Object obj) { + if(obj == null || !(obj instanceof BookmarkedConference)) { + return false; + } + BookmarkedConference conference = (BookmarkedConference)obj; + return conference.getJid().equalsIgnoreCase(jid); + } + + protected void setShared(boolean isShared) { + this.isShared = isShared; + } + + public boolean isShared() { + return isShared; + } } diff --git a/source/org/jivesoftware/smackx/bookmark/BookmarkedURL.java b/source/org/jivesoftware/smackx/bookmark/BookmarkedURL.java index e77f213bc..2df57811a 100644 --- a/source/org/jivesoftware/smackx/bookmark/BookmarkedURL.java +++ b/source/org/jivesoftware/smackx/bookmark/BookmarkedURL.java @@ -12,10 +12,22 @@ package org.jivesoftware.smackx.bookmark; * * @author Derek DeMoro */ -public class BookmarkedURL { +public class BookmarkedURL implements SharedBookmark { private String name; - private String URL; + private final String URL; + private boolean isRss; + private boolean isShared; + + protected BookmarkedURL(String URL) { + this.URL = URL; + } + + protected BookmarkedURL(String URL, String name, boolean isRss) { + this.URL = URL; + this.name = name; + this.isRss = isRss; + } /** * Returns the name representing the URL (eg. Jive Software). This can be used in as a label, or @@ -32,7 +44,7 @@ public class BookmarkedURL { * * @param name the name. */ - public void setName(String name) { + protected void setName(String name) { this.name = name; } @@ -44,14 +56,37 @@ public class BookmarkedURL { public String getURL() { return URL; } - /** - * Sets the URL. + * Set to true if this URL is an RSS or news feed. * - * @param URL the url. + * @param isRss True if the URL is a news feed and false if it is not. */ - public void setURL(String URL) { - this.URL = URL; + protected void setRss(boolean isRss) { + this.isRss = isRss; } + /** + * Returns true if this URL is a news feed. + * + * @return Returns true if this URL is a news feed. + */ + public boolean isRss() { + return isRss; + } + + public boolean equals(Object obj) { + if(!(obj instanceof BookmarkedURL)) { + return false; + } + BookmarkedURL url = (BookmarkedURL)obj; + return url.getURL().equalsIgnoreCase(URL); + } + + protected void setShared(boolean shared) { + this.isShared = shared; + } + + public boolean isShared() { + return isShared; + } } diff --git a/source/org/jivesoftware/smackx/bookmark/Bookmarks.java b/source/org/jivesoftware/smackx/bookmark/Bookmarks.java index fa15964d7..e2bd5afd9 100644 --- a/source/org/jivesoftware/smackx/bookmark/Bookmarks.java +++ b/source/org/jivesoftware/smackx/bookmark/Bookmarks.java @@ -7,15 +7,15 @@ */ package org.jivesoftware.smackx.bookmark; -import org.jivesoftware.smackx.PrivateDataManager; import org.jivesoftware.smackx.packet.PrivateData; import org.jivesoftware.smackx.provider.PrivateDataProvider; import org.xmlpull.v1.XmlPullParser; +import org.xmlpull.v1.XmlPullParserException; import java.util.ArrayList; -import java.util.Collection; import java.util.Iterator; import java.util.List; +import java.io.IOException; /** * Bookmarks is used for storing and retrieving URLS and Conference rooms. @@ -58,9 +58,6 @@ public class Bookmarks implements PrivateData { * Required Empty Constructor to use Bookmarks. */ public Bookmarks() { - // Register own provider for simpler implementation. - PrivateDataManager.addPrivateDataProvider("storage", "storage:bookmarks", new Bookmarks.Provider()); - bookmarkedURLS = new ArrayList(); bookmarkedConferences = new ArrayList(); } @@ -120,7 +117,7 @@ public class Bookmarks implements PrivateData { * * @return a collection of all Bookmarked URLs. */ - public Collection getBookmarkedURLS() { + public List getBookmarkedURLS() { return bookmarkedURLS; } @@ -129,7 +126,7 @@ public class Bookmarks implements PrivateData { * * @return a collection of all Bookmarked Conferences. */ - public Collection getBookmarkedConferences() { + public List getBookmarkedConferences() { return bookmarkedConferences; } @@ -164,13 +161,24 @@ public class Bookmarks implements PrivateData { final Iterator urls = getBookmarkedURLS().iterator(); while (urls.hasNext()) { BookmarkedURL urlStorage = (BookmarkedURL) urls.next(); - buf.append("