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