ObjXMPP  Diff

Differences From Artifact [1569eac957]:

To Artifact [025bb21619]:


41
42
43
44
45
46
47
48
49
50
51
52





53
54
55
56
57
58
59
60
61
62
63
64
65



66
67
68
69
70
71
72

73
74
75
76
77
78
79
80

81
82
83

84
85
86
87
88
89


90
91
92
93
94
95
96
97
98
99
100
101
102



103
104
105
106

107
108
109
110
111
112
113
41
42
43
44
45
46
47





48
49
50
51
52
53
54
55
56
57
58
59
60
61
62



63
64
65
66
67
68
69
70
71

72
73
74
75
76
77
78
79

80
81
82

83
84
85
86
87


88
89
90
91
92
93
94
95
96
97
98
99



100
101
102
103
104
105

106
107
108
109
110
111
112
113







-
-
-
-
-
+
+
+
+
+










-
-
-
+
+
+






-
+







-
+


-
+




-
-
+
+










-
-
-
+
+
+



-
+








@implementation XMPPRoster
- initWithConnection: (XMPPConnection*)connection_
{
	self = [super init];

	@try {
		rosterItems = [[OFMutableDictionary alloc] init];
		connection = connection_;
		[connection addDelegate: self];
		delegates = [[XMPPMulticastDelegate alloc] init];
		dataStorage = [connection dataStorage];
		_rosterItems = [[OFMutableDictionary alloc] init];
		_connection = connection_;
		[_connection addDelegate: self];
		_delegates = [[XMPPMulticastDelegate alloc] init];
		_dataStorage = [_connection dataStorage];
	} @catch (id e) {
		[self release];
		@throw e;
	}

	return self;
}

- (void)dealloc
{
	[connection removeDelegate: self];
	[delegates release];
	[rosterItems release];
	[_connection removeDelegate: self];
	[_delegates release];
	[_rosterItems release];

	[super dealloc];
}

- (OFDictionary*)rosterItems
{
	return [[rosterItems copy] autorelease];
	return [[_rosterItems copy] autorelease];
}

- (void)requestRoster
{
	XMPPIQ *iq;
	OFXMLElement *query;

	rosterRequested = YES;
	_rosterRequested = YES;

	iq = [XMPPIQ IQWithType: @"get"
			     ID: [connection generateStanzaID]];
			     ID: [_connection generateStanzaID]];

	query = [OFXMLElement elementWithName: @"query"
				    namespace: XMPP_NS_ROSTER];

	if ([connection supportsRosterVersioning]) {
		OFString *ver = [dataStorage stringValueForPath: @"roster.ver"];
	if ([_connection supportsRosterVersioning]) {
		OFString *ver = [_dataStorage stringValueForPath: @"roster.ver"];

		if (ver == nil)
			ver = @"";

		[query addAttributeWithName: @"ver"
				stringValue: ver];
	}

	[iq addChild: query];

	[connection sendIQ: iq
	    callbackTarget: self
		  selector: @selector(XMPP_handleInitialRosterForConnection:
	[_connection sendIQ: iq
	     callbackTarget: self
		   selector: @selector(XMPP_handleInitialRosterForConnection:
				IQ:)];
}

- (BOOL)connection: (XMPPConnection*)connection_
- (BOOL)connection: (XMPPConnection*)connection
      didReceiveIQ: (XMPPIQ*)iq
{
	OFXMLElement *rosterElement;
	OFXMLElement *element;
	XMPPRosterItem *rosterItem;

	rosterElement = [iq elementForName: @"query"
121
122
123
124
125
126
127
128
129
130
131




132
133
134
135
136

137
138
139
140
141



142
143
144

145
146
147
148
149
150
151
152
153
154
155
156
157


158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178

179
180

181
182
183
184
185
186


187
188
189
190
191
192
193
194
195
196
197
198

199
200

201
202
203
204
205

206
207
208
209
210

211
212
213

214
215

216
217
218
219

220
221
222
223
224

225
226
227
228
229

230
231
232
233
234
235


236
237
238
239
240
241
242
121
122
123
124
125
126
127




128
129
130
131
132
133
134
135

136
137
138



139
140
141
142
143

144
145
146
147
148
149
150
151
152
153
154
155


156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177

178
179

180
181
182
183
184


185
186
187
188
189
190
191
192
193
194
195
196
197

198
199

200
201
202
203
204

205
206
207
208
209

210
211
212

213
214

215
216
217
218

219
220
221
222
223

224
225
226
227
228

229
230
231
232
233


234
235
236
237
238
239
240
241
242







-
-
-
-
+
+
+
+




-
+


-
-
-
+
+
+


-
+











-
-
+
+




















-
+

-
+




-
-
+
+











-
+

-
+




-
+




-
+


-
+

-
+



-
+




-
+




-
+




-
-
+
+








	element = [rosterElement elementForName: @"item"
				      namespace: XMPP_NS_ROSTER];

	if (element != nil) {
		rosterItem = [self XMPP_rosterItemWithXMLElement: element];

		[delegates broadcastSelector: @selector(
						  roster:didReceiveRosterItem:)
				  withObject: self
				  withObject: rosterItem];
		[_delegates broadcastSelector: @selector(
						   roster:didReceiveRosterItem:)
				   withObject: self
				   withObject: rosterItem];

		[self XMPP_updateRosterItem: rosterItem];
	}

	if ([connection supportsRosterVersioning]) {
	if ([_connection supportsRosterVersioning]) {
		OFString *ver =
		    [[rosterElement attributeForName: @"ver"] stringValue];
		[dataStorage setStringValue: ver
				    forPath: @"roster.ver"];
		[dataStorage save];
		[_dataStorage setStringValue: ver
				     forPath: @"roster.ver"];
		[_dataStorage save];
	}

	[connection_ sendStanza: [iq resultIQ]];
	[connection sendStanza: [iq resultIQ]];

	return YES;
}

- (void)addRosterItem: (XMPPRosterItem*)rosterItem
{
	[self updateRosterItem: rosterItem];
}

- (void)updateRosterItem: (XMPPRosterItem*)rosterItem
{
	XMPPIQ *iq = [XMPPIQ IQWithType: @"set"
				     ID: [connection generateStanzaID]];
	XMPPIQ *IQ = [XMPPIQ IQWithType: @"set"
				     ID: [_connection generateStanzaID]];
	OFXMLElement *query = [OFXMLElement elementWithName: @"query"
						  namespace: XMPP_NS_ROSTER];
	OFXMLElement *item = [OFXMLElement elementWithName: @"item"
						 namespace: XMPP_NS_ROSTER];
	OFEnumerator *enumerator;
	OFString *group;

	[item addAttributeWithName: @"jid"
		       stringValue: [[rosterItem JID] bareJID]];
	if ([rosterItem name] != nil)
		[item addAttributeWithName: @"name"
			       stringValue: [rosterItem name]];

	enumerator = [[rosterItem groups] objectEnumerator];
	while ((group = [enumerator nextObject]) != nil)
		[item addChild: [OFXMLElement elementWithName: @"group"
						    namespace: XMPP_NS_ROSTER
						  stringValue: group]];

	[query addChild: item];
	[iq addChild: query];
	[IQ addChild: query];

	[connection sendStanza: iq];
	[_connection sendStanza: IQ];
}

- (void)deleteRosterItem: (XMPPRosterItem*)rosterItem
{
	XMPPIQ *iq = [XMPPIQ IQWithType: @"set"
				     ID: [connection generateStanzaID]];
	XMPPIQ *IQ = [XMPPIQ IQWithType: @"set"
				     ID: [_connection generateStanzaID]];
	OFXMLElement *query = [OFXMLElement elementWithName: @"query"
						  namespace: XMPP_NS_ROSTER];
	OFXMLElement *item = [OFXMLElement elementWithName: @"item"
						 namespace: XMPP_NS_ROSTER];

	[item addAttributeWithName: @"jid"
		       stringValue: [[rosterItem JID] bareJID]];
	[item addAttributeWithName: @"subscription"
		       stringValue: @"remove"];

	[query addChild: item];
	[iq addChild: query];
	[IQ addChild: query];

	[connection sendStanza: iq];
	[_connection sendStanza: IQ];
}

- (void)addDelegate: (id <XMPPRosterDelegate>)delegate
{
	[delegates addDelegate: delegate];
	[_delegates addDelegate: delegate];
}

- (void)removeDelegate: (id <XMPPRosterDelegate>)delegate
{
	[delegates removeDelegate: delegate];
	[_delegates removeDelegate: delegate];
}

- (void)setDataStorage: (id <XMPPStorage>)dataStorage_
- (void)setDataStorage: (id <XMPPStorage>)dataStorage
{
	if (rosterRequested)
	if (_rosterRequested)
		@throw [OFInvalidArgumentException
		    exceptionWithClass: [self class]];

	dataStorage = dataStorage_;
	_dataStorage = dataStorage;
}

- (XMPPConnection*)connection
{
	return connection;
	return _connection;
}

- (id <XMPPStorage>)dataStorage
{
	return dataStorage;
	return _dataStorage;
}

- (void)XMPP_updateRosterItem: (XMPPRosterItem*)rosterItem
{
	if ([connection supportsRosterVersioning]) {
		OFMutableDictionary *items = [[[dataStorage dictionaryForPath:
	if ([_connection supportsRosterVersioning]) {
		OFMutableDictionary *items = [[[_dataStorage dictionaryForPath:
		    @"roster.items"] mutableCopy] autorelease];

		if (items == nil)
			items = [OFMutableDictionary dictionary];

		if (![[rosterItem subscription] isEqual: @"remove"]) {
			OFMutableDictionary *item = [OFMutableDictionary
254
255
256
257
258
259
260
261
262


263
264
265
266
267


268
269

270
271
272
273
274
275
276
254
255
256
257
258
259
260


261
262
263
264
265


266
267
268

269
270
271
272
273
274
275
276







-
-
+
+



-
-
+
+

-
+







					 forKey: @"groups"];

			[items setObject: item
				  forKey: [[rosterItem JID] bareJID]];
		} else
			[items removeObjectForKey: [[rosterItem JID] bareJID]];

		[dataStorage setDictionary: items
				   forPath: @"roster.items"];
		[_dataStorage setDictionary: items
				    forPath: @"roster.items"];
	}

	if (![[rosterItem subscription] isEqual: @"remove"])
		[rosterItems setObject: rosterItem
				forKey: [[rosterItem JID] bareJID]];
		[_rosterItems setObject: rosterItem
				 forKey: [[rosterItem JID] bareJID]];
	else
		[rosterItems removeObjectForKey: [[rosterItem JID] bareJID]];
		[_rosterItems removeObjectForKey: [[rosterItem JID] bareJID]];
}

- (XMPPRosterItem*)XMPP_rosterItemWithXMLElement: (OFXMLElement*)element
{
	OFString *subscription;
	OFEnumerator *groupEnumerator;
	OFXMLElement *groupElement;
311
312
313
314
315
316
317
318

319
320

321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341


342
343
344
345


346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364

365
366
367
368
369



370
371
372
373


374
375
311
312
313
314
315
316
317

318
319

320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339


340
341
342
343


344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363

364
365
366



367
368
369
370
371


372
373
374
375







-
+

-
+



















-
-
+
+


-
-
+
+


















-
+


-
-
-
+
+
+


-
-
+
+


	OFXMLElement *rosterElement;
	OFEnumerator *enumerator;
	OFXMLElement *element;

	rosterElement = [iq elementForName: @"query"
				 namespace: XMPP_NS_ROSTER];

	if ([connection supportsRosterVersioning]) {
	if ([_connection supportsRosterVersioning]) {
		if (rosterElement == nil) {
			OFDictionary *items = [dataStorage
			OFDictionary *items = [_dataStorage
			    dictionaryForPath: @"roster.items"];
			OFEnumerator *enumerator = [items objectEnumerator];
			OFDictionary *item;

			while ((item = [enumerator nextObject]) != nil) {
				XMPPRosterItem *rosterItem;
				XMPPJID *JID;

				rosterItem = [XMPPRosterItem rosterItem];
				JID = [XMPPJID JIDWithString:
					  [item objectForKey: @"JID"]];
				[rosterItem setJID: JID];
				[rosterItem setName:
				    [item objectForKey: @"name"]];
				[rosterItem setSubscription:
				    [item objectForKey: @"subscription"]];
				[rosterItem setGroups:
				    [item objectForKey: @"groups"]];

				[rosterItems setObject: rosterItem
						forKey: [JID bareJID]];
				[_rosterItems setObject: rosterItem
						 forKey: [JID bareJID]];
			}
		} else
			[dataStorage setDictionary: nil
					   forPath: @"roster.items"];
			[_dataStorage setDictionary: nil
					    forPath: @"roster.items"];
	}

	enumerator = [[rosterElement children] objectEnumerator];
	while ((element = [enumerator nextObject]) != nil) {
		OFAutoreleasePool *pool;
		XMPPRosterItem *rosterItem;

		if (![[element name] isEqual: @"item"] ||
		    ![[element namespace] isEqual: XMPP_NS_ROSTER])
			continue;

		pool = [OFAutoreleasePool new];
		rosterItem = [self XMPP_rosterItemWithXMLElement: element];

		[self XMPP_updateRosterItem: rosterItem];
		[pool release];
	}

	if ([connection supportsRosterVersioning] && rosterElement != nil) {
	if ([_connection supportsRosterVersioning] && rosterElement != nil) {
		OFString *ver =
		    [[rosterElement attributeForName: @"ver"] stringValue];
		[dataStorage setStringValue: ver
				    forPath: @"roster.ver"];
		[dataStorage save];
		[_dataStorage setStringValue: ver
				     forPath: @"roster.ver"];
		[_dataStorage save];
	}

	[delegates broadcastSelector: @selector(rosterWasReceived:)
			  withObject: self];
	[_delegates broadcastSelector: @selector(rosterWasReceived:)
			   withObject: self];
}
@end