Source code: org/jabber/jabberbeans/RosterBean.java
1 package org.jabber.jabberbeans;
2
3 import java.io.Serializable;
4 import java.io.IOException;
5 import java.util.Vector;
6 import java.util.Enumeration;
7 import org.jabber.jabberbeans.Extension.Extension;
8 import org.jabber.jabberbeans.Extension.QueryExtension;
9 import org.jabber.jabberbeans.Extension.IQRosterExtension;
10 import org.jabber.jabberbeans.Extension.IQRosterExtensionBuilder;
11
12 /**
13 * RosterBean is a bean to gain and utilize the roster information in jabber.
14 * A 'Roster' is a list of users, a type of subscription list or address book,
15 * if you will. By using a roster, you can get the status of other users
16 * (online/offline, etc), subscribe and unsubscribe users, as well as change
17 * your own status.
18 *
19 * This bean hooks into an IQBean, it will not work until it is given a
20 * ConnectionBean to handle. RosterBean to ConnectionBean is a many to one
21 * relation - one ConnectionBean can have many RosterBeans, but if software
22 * wants to use more than a singular server connection, there is need for
23 * multiple RosterBeans, one per ConnectionBean.
24 *
25 * @author David Waite <a href="mailto:mass@ufl.edu"><i><mass@ufl.edu>
26 * </i></a>
27 * @author $Author: mass $
28 * @version $Revision: 1.2 $
29 */
30 public class RosterBean
31 implements Serializable
32 {
33 private IQBean connection;
34 private Vector rosterListeners=new Vector();
35 private IQRosterExtension currentRoster;
36
37 /**
38 * a infoquery builder for sending roster change requests. Not created
39 * until first use.
40 */
41 private InfoQueryBuilder IQBuilder=null;
42
43 /**
44 * a roster extension builder for sending roster change requests. Not
45 * created until first use.
46 */
47 private IQRosterExtensionBuilder rosterBuilder=null;
48
49 /**
50 * a roster item builder for sending custom roster changes. Not created
51 * until first use.
52 */
53 private RosterItemBuilder rosterItemBuilder=null;
54
55 class RosterIQPacketListener
56 implements PacketListener
57 {
58 public void receivedPacket(Packet l)
59 {
60 if (!(l instanceof InfoQuery))
61 return;
62 Extension e=((InfoQuery)l).getQueryExtension();
63
64 if (!(e instanceof IQRosterExtension))
65 return;
66 //TODO: add code to modify current roster image based on
67 //new data. Replacement is basically shown by if the type is not
68 //'result' of the IQ
69 if (((InfoQuery)l).getType().equals("result"))
70 {
71 //the results of a get will be the results of a full fetch
72 currentRoster=(IQRosterExtension)e;
73 fireUserRosterReplaced(currentRoster);
74 }
75 else
76 {
77 //TODO: add modification code
78 fireUserRosterChanged((IQRosterExtension)e);
79 }
80 }
81
82 public void sentPacket(Packet l)
83 {
84 }
85 }
86 public RosterBean()
87 {
88 }
89 public void setIQBean(IQBean connection)
90 {
91 this.connection=connection;
92 }
93 public IQBean getIQBean()
94 {
95 return connection;
96 }
97
98 public void refreshRoster()
99 throws InstantiationException,IOException
100 {
101 //create builder if not used before.
102 if (IQBuilder==null)
103 IQBuilder=new InfoQueryBuilder();
104 else
105 //we have used this builder before - make sure it is clean.
106 IQBuilder.reset();
107 IQBuilder.setType("get");
108
109 //this should never throw an exception
110 IQBuilder.setQueryExtension(new IQRosterExtension());
111
112 //this also should just work.
113 connection.send((InfoQuery)IQBuilder.build());
114 }
115
116
117 public synchronized void addRosterItem(RosterItem ri)
118 throws InstantiationException,IOException
119 {
120 //create builder if not used before.
121 if (IQBuilder==null)
122 IQBuilder=new InfoQueryBuilder();
123 else
124 //we have used this builder before - make sure it is clean.
125 IQBuilder.reset();
126 IQBuilder.setType("set");
127
128 if(rosterBuilder==null)
129 rosterBuilder=new IQRosterExtensionBuilder();
130 else
131 rosterBuilder.reset();
132
133 rosterBuilder.addRosterItem(ri);
134
135 //this should never throw an exception, because we added the
136 //roster item above first
137 IQBuilder.setQueryExtension((QueryExtension)rosterBuilder.build());
138
139 //this also should just work.
140 connection.send((InfoQuery)IQBuilder.build());
141 }
142 public synchronized void delRosterItem(RosterItem ri)
143 throws InstantiationException,IOException
144 {
145 //create builder if not used before.
146 if (IQBuilder==null)
147 IQBuilder=new InfoQueryBuilder();
148 else
149 //we have used this builder before - make sure it is clean.
150 IQBuilder.reset();
151 IQBuilder.setType("set");
152
153 if(rosterBuilder==null)
154 rosterBuilder=new IQRosterExtensionBuilder();
155 else
156 rosterBuilder.reset();
157
158 if (rosterItemBuilder==null)
159 rosterItemBuilder=new RosterItemBuilder();
160 else
161 //we have used this builder before - make sure it is clean.
162 rosterItemBuilder.reset();
163
164 // copy existing roster item
165 rosterItemBuilder.copyItem(ri);
166
167 //change subscription type to 'remove' to tell the server to delete the
168 //item
169 rosterItemBuilder.setSubscriptionType("remove");
170
171 //this should never throw an exception, since we are based on
172 //the original roster item.
173 rosterBuilder.addRosterItem(rosterItemBuilder.build());
174
175 //this should never throw an exception, because we added the
176 //roster item above first
177 IQBuilder.setQueryExtension((QueryExtension)rosterBuilder.build());
178
179 //this also should just work.
180 connection.send((InfoQuery)IQBuilder.build());
181 }
182
183 public synchronized void addRosterListener(RosterListener l)
184 {
185 if(!rosterListeners.contains(l))
186 rosterListeners.addElement(l);
187 }
188 public synchronized void removeRosterListener(RosterListener l)
189 {
190 rosterListeners.removeElement(l);
191 }
192
193 private void fireUserRosterChanged(IQRosterExtension r)
194 {
195 for (Enumeration e = rosterListeners.elements(); e.hasMoreElements(); )
196 {
197 ((RosterListener)e.nextElement()).changedRoster(r);
198 }
199 }
200 private void fireUserRosterReplaced(IQRosterExtension r)
201 {
202 for (Enumeration e = rosterListeners.elements(); e.hasMoreElements(); )
203 {
204 ((RosterListener)e.nextElement()).replacedRoster(r);
205 }
206 }
207 }