001/** 002 * 003 * Copyright 2003-2007 Jive Software. 004 * 005 * Licensed under the Apache License, Version 2.0 (the "License"); 006 * you may not use this file except in compliance with the License. 007 * You may obtain a copy of the License at 008 * 009 * http://www.apache.org/licenses/LICENSE-2.0 010 * 011 * Unless required by applicable law or agreed to in writing, software 012 * distributed under the License is distributed on an "AS IS" BASIS, 013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 014 * See the License for the specific language governing permissions and 015 * limitations under the License. 016 */ 017package org.jivesoftware.smackx.bookmarks; 018 019import java.io.IOException; 020import java.util.ArrayList; 021import java.util.List; 022 023import org.jivesoftware.smack.util.ParserUtils; 024import org.jivesoftware.smack.util.XmlStringBuilder; 025 026import org.jivesoftware.smackx.iqprivate.packet.PrivateData; 027import org.jivesoftware.smackx.iqprivate.provider.PrivateDataProvider; 028 029import org.jxmpp.jid.EntityBareJid; 030import org.jxmpp.jid.parts.Resourcepart; 031import org.xmlpull.v1.XmlPullParser; 032import org.xmlpull.v1.XmlPullParserException; 033 034/** 035 * Bookmarks is used for storing and retrieving URLS and Conference rooms. 036 * Bookmark Storage (XEP-0048) defined a protocol for the storage of bookmarks to conference rooms and other entities 037 * in a Jabber user's account. 038 * See the following code sample for saving Bookmarks: 039 * <p/> 040 * <pre> 041 * XMPPConnection con = new XMPPTCPConnection("jabber.org"); 042 * con.login("john", "doe"); 043 * Bookmarks bookmarks = new Bookmarks(); 044 * <p/> 045 * // Bookmark a URL 046 * BookmarkedURL url = new BookmarkedURL(); 047 * url.setName("Google"); 048 * url.setURL("http://www.jivesoftware.com"); 049 * bookmarks.addURL(url); 050 * // Bookmark a Conference room. 051 * BookmarkedConference conference = new BookmarkedConference(); 052 * conference.setName("My Favorite Room"); 053 * conference.setAutoJoin("true"); 054 * conference.setJID("dev@conference.jivesoftware.com"); 055 * bookmarks.addConference(conference); 056 * // Save Bookmarks using PrivateDataManager. 057 * PrivateDataManager manager = new PrivateDataManager(con); 058 * manager.setPrivateData(bookmarks); 059 * <p/> 060 * <p/> 061 * LastActivity activity = LastActivity.getLastActivity(con, "xray@jabber.org"); 062 * </pre> 063 * 064 * @author Derek DeMoro 065 */ 066public class Bookmarks implements PrivateData { 067 068 public static final String NAMESPACE = "storage:bookmarks"; 069 public static final String ELEMENT = "storage"; 070 071 private List<BookmarkedURL> bookmarkedURLS; 072 private List<BookmarkedConference> bookmarkedConferences; 073 074 /** 075 * Required Empty Constructor to use Bookmarks. 076 */ 077 public Bookmarks() { 078 bookmarkedURLS = new ArrayList<BookmarkedURL>(); 079 bookmarkedConferences = new ArrayList<BookmarkedConference>(); 080 } 081 082 /** 083 * Adds a BookmarkedURL. 084 * 085 * @param bookmarkedURL the bookmarked bookmarkedURL. 086 */ 087 public void addBookmarkedURL(BookmarkedURL bookmarkedURL) { 088 bookmarkedURLS.add(bookmarkedURL); 089 } 090 091 /** 092 * Removes a bookmarked bookmarkedURL. 093 * 094 * @param bookmarkedURL the bookmarked bookmarkedURL to remove. 095 */ 096 public void removeBookmarkedURL(BookmarkedURL bookmarkedURL) { 097 bookmarkedURLS.remove(bookmarkedURL); 098 } 099 100 /** 101 * Removes all BookmarkedURLs from user's bookmarks. 102 */ 103 public void clearBookmarkedURLS() { 104 bookmarkedURLS.clear(); 105 } 106 107 /** 108 * Add a BookmarkedConference to bookmarks. 109 * 110 * @param bookmarkedConference the conference to remove. 111 */ 112 public void addBookmarkedConference(BookmarkedConference bookmarkedConference) { 113 bookmarkedConferences.add(bookmarkedConference); 114 } 115 116 /** 117 * Removes a BookmarkedConference. 118 * 119 * @param bookmarkedConference the BookmarkedConference to remove. 120 */ 121 public void removeBookmarkedConference(BookmarkedConference bookmarkedConference) { 122 bookmarkedConferences.remove(bookmarkedConference); 123 } 124 125 /** 126 * Removes all BookmarkedConferences from Bookmarks. 127 */ 128 public void clearBookmarkedConferences() { 129 bookmarkedConferences.clear(); 130 } 131 132 /** 133 * Returns a Collection of all Bookmarked URLs for this user. 134 * 135 * @return a collection of all Bookmarked URLs. 136 */ 137 public List<BookmarkedURL> getBookmarkedURLS() { 138 return bookmarkedURLS; 139 } 140 141 /** 142 * Returns a Collection of all Bookmarked Conference for this user. 143 * 144 * @return a collection of all Bookmarked Conferences. 145 */ 146 public List<BookmarkedConference> getBookmarkedConferences() { 147 return bookmarkedConferences; 148 } 149 150 151 /** 152 * Returns the root element name. 153 * 154 * @return the element name. 155 */ 156 @Override 157 public String getElementName() { 158 return ELEMENT; 159 } 160 161 /** 162 * Returns the root element XML namespace. 163 * 164 * @return the namespace. 165 */ 166 @Override 167 public String getNamespace() { 168 return NAMESPACE; 169 } 170 171 /** 172 * Returns the XML representation of the PrivateData. 173 * 174 * @return the private data as XML. 175 */ 176 @Override 177 public XmlStringBuilder toXML() { 178 XmlStringBuilder buf = new XmlStringBuilder(); 179 buf.halfOpenElement(ELEMENT).xmlnsAttribute(NAMESPACE).rightAngleBracket(); 180 181 for (BookmarkedURL urlStorage : getBookmarkedURLS()) { 182 if (urlStorage.isShared()) { 183 continue; 184 } 185 buf.halfOpenElement("url").attribute("name", urlStorage.getName()).attribute("url", urlStorage.getURL()); 186 buf.condAttribute(urlStorage.isRss(), "rss", "true"); 187 buf.closeEmptyElement(); 188 } 189 190 // Add Conference additions 191 for (BookmarkedConference conference : getBookmarkedConferences()) { 192 if (conference.isShared()) { 193 continue; 194 } 195 buf.halfOpenElement("conference"); 196 buf.attribute("name", conference.getName()); 197 buf.attribute("autojoin", Boolean.toString(conference.isAutoJoin())); 198 buf.attribute("jid", conference.getJid()); 199 buf.rightAngleBracket(); 200 201 buf.optElement("nick", conference.getNickname()); 202 buf.optElement("password", conference.getPassword()); 203 204 buf.closeElement("conference"); 205 } 206 207 buf.closeElement(ELEMENT); 208 return buf; 209 } 210 211 /** 212 * The IQ Provider for BookmarkStorage. 213 * 214 * @author Derek DeMoro 215 */ 216 public static class Provider implements PrivateDataProvider { 217 218 /** 219 * Empty Constructor for PrivateDataProvider. 220 */ 221 public Provider() { 222 super(); 223 } 224 225 @Override 226 public PrivateData parsePrivateData(XmlPullParser parser) throws XmlPullParserException, IOException { 227 Bookmarks storage = new Bookmarks(); 228 229 boolean done = false; 230 while (!done) { 231 int eventType = parser.next(); 232 if (eventType == XmlPullParser.START_TAG && "url".equals(parser.getName())) { 233 final BookmarkedURL urlStorage = getURLStorage(parser); 234 if (urlStorage != null) { 235 storage.addBookmarkedURL(urlStorage); 236 } 237 } 238 else if (eventType == XmlPullParser.START_TAG && 239 "conference".equals(parser.getName())) 240 { 241 final BookmarkedConference conference = getConferenceStorage(parser); 242 storage.addBookmarkedConference(conference); 243 } 244 else if (eventType == XmlPullParser.END_TAG && "storage".equals(parser.getName())) 245 { 246 done = true; 247 } 248 } 249 250 251 return storage; 252 } 253 } 254 255 private static BookmarkedURL getURLStorage(XmlPullParser parser) throws IOException, XmlPullParserException { 256 String name = parser.getAttributeValue("", "name"); 257 String url = parser.getAttributeValue("", "url"); 258 String rssString = parser.getAttributeValue("", "rss"); 259 boolean rss = rssString != null && "true".equals(rssString); 260 261 BookmarkedURL urlStore = new BookmarkedURL(url, name, rss); 262 boolean done = false; 263 while (!done) { 264 int eventType = parser.next(); 265 if (eventType == XmlPullParser.START_TAG 266 && "shared_bookmark".equals(parser.getName())) { 267 urlStore.setShared(true); 268 } 269 else if (eventType == XmlPullParser.END_TAG && "url".equals(parser.getName())) { 270 done = true; 271 } 272 } 273 return urlStore; 274 } 275 276 private static BookmarkedConference getConferenceStorage(XmlPullParser parser) throws XmlPullParserException, IOException { 277 String name = parser.getAttributeValue("", "name"); 278 String autojoin = parser.getAttributeValue("", "autojoin"); 279 EntityBareJid jid = ParserUtils.getBareJidAttribute(parser); 280 281 BookmarkedConference conf = new BookmarkedConference(jid); 282 conf.setName(name); 283 conf.setAutoJoin(Boolean.valueOf(autojoin).booleanValue()); 284 285 // Check for nickname 286 boolean done = false; 287 while (!done) { 288 int eventType = parser.next(); 289 if (eventType == XmlPullParser.START_TAG && "nick".equals(parser.getName())) { 290 String nickString = parser.nextText(); 291 conf.setNickname(Resourcepart.from(nickString)); 292 } 293 else if (eventType == XmlPullParser.START_TAG && "password".equals(parser.getName())) { 294 conf.setPassword(parser.nextText()); 295 } 296 else if (eventType == XmlPullParser.START_TAG 297 && "shared_bookmark".equals(parser.getName())) { 298 conf.setShared(true); 299 } 300 else if (eventType == XmlPullParser.END_TAG && "conference".equals(parser.getName())) { 301 done = true; 302 } 303 } 304 305 306 return conf; 307 } 308}