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 * <pre> 040 * XMPPConnection con = new XMPPTCPConnection("jabber.org"); 041 * con.login("john", "doe"); 042 * Bookmarks bookmarks = new Bookmarks(); 043 * // Bookmark a URL 044 * BookmarkedURL url = new BookmarkedURL(); 045 * url.setName("Google"); 046 * url.setURL("http://www.jivesoftware.com"); 047 * bookmarks.addURL(url); 048 * // Bookmark a Conference room. 049 * BookmarkedConference conference = new BookmarkedConference(); 050 * conference.setName("My Favorite Room"); 051 * conference.setAutoJoin("true"); 052 * conference.setJID("dev@conference.jivesoftware.com"); 053 * bookmarks.addConference(conference); 054 * // Save Bookmarks using PrivateDataManager. 055 * PrivateDataManager manager = new PrivateDataManager(con); 056 * manager.setPrivateData(bookmarks); 057 * LastActivity activity = LastActivity.getLastActivity(con, "xray@jabber.org"); 058 * </pre> 059 * 060 * @author Derek DeMoro 061 */ 062public class Bookmarks implements PrivateData { 063 064 public static final String NAMESPACE = "storage:bookmarks"; 065 public static final String ELEMENT = "storage"; 066 067 private final List<BookmarkedURL> bookmarkedURLS; 068 private final List<BookmarkedConference> bookmarkedConferences; 069 070 /** 071 * Required Empty Constructor to use Bookmarks. 072 */ 073 public Bookmarks() { 074 bookmarkedURLS = new ArrayList<>(); 075 bookmarkedConferences = new ArrayList<>(); 076 } 077 078 /** 079 * Adds a BookmarkedURL. 080 * 081 * @param bookmarkedURL the bookmarked bookmarkedURL. 082 */ 083 public void addBookmarkedURL(BookmarkedURL bookmarkedURL) { 084 bookmarkedURLS.add(bookmarkedURL); 085 } 086 087 /** 088 * Removes a bookmarked bookmarkedURL. 089 * 090 * @param bookmarkedURL the bookmarked bookmarkedURL to remove. 091 */ 092 public void removeBookmarkedURL(BookmarkedURL bookmarkedURL) { 093 bookmarkedURLS.remove(bookmarkedURL); 094 } 095 096 /** 097 * Removes all BookmarkedURLs from user's bookmarks. 098 */ 099 public void clearBookmarkedURLS() { 100 bookmarkedURLS.clear(); 101 } 102 103 /** 104 * Add a BookmarkedConference to bookmarks. 105 * 106 * @param bookmarkedConference the conference to remove. 107 */ 108 public void addBookmarkedConference(BookmarkedConference bookmarkedConference) { 109 bookmarkedConferences.add(bookmarkedConference); 110 } 111 112 /** 113 * Removes a BookmarkedConference. 114 * 115 * @param bookmarkedConference the BookmarkedConference to remove. 116 */ 117 public void removeBookmarkedConference(BookmarkedConference bookmarkedConference) { 118 bookmarkedConferences.remove(bookmarkedConference); 119 } 120 121 /** 122 * Removes all BookmarkedConferences from Bookmarks. 123 */ 124 public void clearBookmarkedConferences() { 125 bookmarkedConferences.clear(); 126 } 127 128 /** 129 * Returns a Collection of all Bookmarked URLs for this user. 130 * 131 * @return a collection of all Bookmarked URLs. 132 */ 133 public List<BookmarkedURL> getBookmarkedURLS() { 134 return bookmarkedURLS; 135 } 136 137 /** 138 * Returns a Collection of all Bookmarked Conference for this user. 139 * 140 * @return a collection of all Bookmarked Conferences. 141 */ 142 public List<BookmarkedConference> getBookmarkedConferences() { 143 return bookmarkedConferences; 144 } 145 146 147 /** 148 * Returns the root element name. 149 * 150 * @return the element name. 151 */ 152 @Override 153 public String getElementName() { 154 return ELEMENT; 155 } 156 157 /** 158 * Returns the root element XML namespace. 159 * 160 * @return the namespace. 161 */ 162 @Override 163 public String getNamespace() { 164 return NAMESPACE; 165 } 166 167 /** 168 * Returns the XML representation of the PrivateData. 169 * 170 * @return the private data as XML. 171 */ 172 @Override 173 public XmlStringBuilder toXML() { 174 XmlStringBuilder buf = new XmlStringBuilder(); 175 buf.halfOpenElement(ELEMENT).xmlnsAttribute(NAMESPACE).rightAngleBracket(); 176 177 for (BookmarkedURL urlStorage : getBookmarkedURLS()) { 178 if (urlStorage.isShared()) { 179 continue; 180 } 181 buf.halfOpenElement("url").attribute("name", urlStorage.getName()).attribute("url", urlStorage.getURL()); 182 buf.condAttribute(urlStorage.isRss(), "rss", "true"); 183 buf.closeEmptyElement(); 184 } 185 186 // Add Conference additions 187 for (BookmarkedConference conference : getBookmarkedConferences()) { 188 if (conference.isShared()) { 189 continue; 190 } 191 buf.halfOpenElement("conference"); 192 buf.attribute("name", conference.getName()); 193 buf.attribute("autojoin", Boolean.toString(conference.isAutoJoin())); 194 buf.attribute("jid", conference.getJid()); 195 buf.rightAngleBracket(); 196 197 buf.optElement("nick", conference.getNickname()); 198 buf.optElement("password", conference.getPassword()); 199 200 buf.closeElement("conference"); 201 } 202 203 buf.closeElement(ELEMENT); 204 return buf; 205 } 206 207 /** 208 * The IQ Provider for BookmarkStorage. 209 * 210 * @author Derek DeMoro 211 */ 212 public static class Provider implements PrivateDataProvider { 213 214 /** 215 * Empty Constructor for PrivateDataProvider. 216 */ 217 public Provider() { 218 super(); 219 } 220 221 @Override 222 public PrivateData parsePrivateData(XmlPullParser parser) throws XmlPullParserException, IOException { 223 Bookmarks storage = new Bookmarks(); 224 225 boolean done = false; 226 while (!done) { 227 int eventType = parser.next(); 228 if (eventType == XmlPullParser.START_TAG && "url".equals(parser.getName())) { 229 final BookmarkedURL urlStorage = getURLStorage(parser); 230 if (urlStorage != null) { 231 storage.addBookmarkedURL(urlStorage); 232 } 233 } 234 else if (eventType == XmlPullParser.START_TAG && 235 "conference".equals(parser.getName())) { 236 final BookmarkedConference conference = getConferenceStorage(parser); 237 storage.addBookmarkedConference(conference); 238 } 239 else if (eventType == XmlPullParser.END_TAG && "storage".equals(parser.getName())) { 240 done = true; 241 } 242 } 243 244 245 return storage; 246 } 247 } 248 249 private static BookmarkedURL getURLStorage(XmlPullParser parser) throws IOException, XmlPullParserException { 250 String name = parser.getAttributeValue("", "name"); 251 String url = parser.getAttributeValue("", "url"); 252 String rssString = parser.getAttributeValue("", "rss"); 253 boolean rss = rssString != null && "true".equals(rssString); 254 255 BookmarkedURL urlStore = new BookmarkedURL(url, name, rss); 256 boolean done = false; 257 while (!done) { 258 int eventType = parser.next(); 259 if (eventType == XmlPullParser.START_TAG 260 && "shared_bookmark".equals(parser.getName())) { 261 urlStore.setShared(true); 262 } 263 else if (eventType == XmlPullParser.END_TAG && "url".equals(parser.getName())) { 264 done = true; 265 } 266 } 267 return urlStore; 268 } 269 270 private static BookmarkedConference getConferenceStorage(XmlPullParser parser) throws XmlPullParserException, IOException { 271 String name = parser.getAttributeValue("", "name"); 272 boolean autojoin = ParserUtils.getBooleanAttribute(parser, "autojoin", false); 273 EntityBareJid jid = ParserUtils.getBareJidAttribute(parser); 274 275 BookmarkedConference conf = new BookmarkedConference(jid); 276 conf.setName(name); 277 conf.setAutoJoin(autojoin); 278 279 // Check for nickname 280 boolean done = false; 281 while (!done) { 282 int eventType = parser.next(); 283 if (eventType == XmlPullParser.START_TAG && "nick".equals(parser.getName())) { 284 String nickString = parser.nextText(); 285 conf.setNickname(Resourcepart.from(nickString)); 286 } 287 else if (eventType == XmlPullParser.START_TAG && "password".equals(parser.getName())) { 288 conf.setPassword(parser.nextText()); 289 } 290 else if (eventType == XmlPullParser.START_TAG 291 && "shared_bookmark".equals(parser.getName())) { 292 conf.setShared(true); 293 } 294 else if (eventType == XmlPullParser.END_TAG && "conference".equals(parser.getName())) { 295 done = true; 296 } 297 } 298 299 300 return conf; 301 } 302}