-
Notifications
You must be signed in to change notification settings - Fork 6
/
TNStrophePrivateStorage.j
154 lines (130 loc) · 5.62 KB
/
TNStrophePrivateStorage.j
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
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
114
115
116
117
118
119
120
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
/*
* TNStrophePrivateStorage.j
*
* Copyright (C) 2010 Antoine Mercadal <antoine.mercadal@inframonde.eu>
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
@import "Resources/Strophe/strophe.js"
@import "TNStropheConnection.j"
@import "TNStropheUtils.j"
TNStrophePrivateStorageGetErrorNotification = @"TNStrophePrivateStorageGetErrorNotification";
TNStrophePrivateStorageSetErrorNotification = @"TNStrophePrivateStorageSetErrorNotification";
TNStrophePrivateStorageSetNotification = @"TNStrophePrivateStorageSetNotification";
/*! @ingroup strophecappuccino
This class allows to store random objects in XMPP private storage
*/
@implementation TNStrophePrivateStorage : CPObject
{
CPString _namespace @accessors(property=namespace);
TNStropheConnection _connection @accessors(property=connection);
}
#pragma mark -
#pragma mark Initialization
/*! return an initialized TNStrophePrivateStorage with given connection and namespace
@param aConnection the TNStropheConnection
@param aNamespace the namespace of the storage
@return a new TNStrophePrivateStorage
*/
+ (TNStropheConnection)strophePrivateStorageWithConnection:(TNStropheConnection)aConnection namespace:(CPString)aNamespace
{
return [[TNStrophePrivateStorage alloc] initWithConnection:aConnection namespace:aNamespace];
}
/*! initialize TNStrophePrivateStorage with given connection and namespace
@param aConnection the TNStropheConnection
@param aNamespace the namespace of the storage
@return a new TNStrophePrivateStorage
*/
- (TNStropheConnection)initWithConnection:(TNStropheConnection)aConnection namespace:(CPString)aNamespace
{
if (self = [super init])
{
_connection = aConnection;
_namespace = aNamespace
}
return self;
}
#pragma mark -
#pragma mark Storage
/*! set the given object for the given key
@param anObject the obect to store
@param aKey the associated key
*/
- (void)setObject:(id)anObject forKey:(CPString)aKey
{
var data = [CPKeyedArchiver archivedDataWithRootObject:anObject],
uid = [_connection getUniqueId],
stanza = [TNStropheStanza iqWithAttributes:{@"id": uid, @"type": @"set"}],
params = [CPDictionary dictionaryWithObjectsAndKeys:uid, @"id"];
[stanza addChildWithName:@"query" andAttributes:{@"xmlns": Strophe.NS.PRIVATE_STORAGE}];
[stanza addChildWithName:aKey andAttributes:{@"xmlns": _namespace}];
[stanza addTextNode:[data rawString]];
[_connection registerSelector:@selector(_didSetObject:object:) ofObject:self withDict:params userInfo:anObject];
[_connection send:stanza];
}
/*! @ignore
called when the storage is sucessfull
@params aStanza the stanza containing the result
@params anObject the object that has been set
*/
- (BOOL)_didSetObject:(TNStropheStanza)aStanza object:(id)anObject
{
if ([aStanza type] == @"result")
[[CPNotificationCenter defaultCenter] postNotificationName:TNStrophePrivateStorageSetNotification object:self userInfo:anObject];
else
[[CPNotificationCenter defaultCenter] postNotificationName:TNStrophePrivateStorageSetErrorNotification object:self userInfo:aStanza];
return NO;
}
/*! get the object associated to the given key. This message will send to target
@param aKey the key
@param aTarget the target that will receive the message containing the object
@param aSelector the message that will be send to the target
*/
- (id)objectForKey:(CPString)aKey target:(id)aTarget selector:(SEL)aSelector
{
var uid = [_connection getUniqueId],
stanza = [TNStropheStanza iqWithAttributes:{@"id": uid, @"type": @"get"}],
params = [CPDictionary dictionaryWithObjectsAndKeys:uid, @"id"],
listener = {@"target": aTarget, @"selector": aSelector, @"key": aKey};
[stanza addChildWithName:@"query" andAttributes:{@"xmlns": Strophe.NS.PRIVATE_STORAGE}];
[stanza addChildWithName:aKey andAttributes:{@"xmlns": _namespace}];
[_connection registerSelector:@selector(_didReceiveObject:userInfo:) ofObject:self withDict:params userInfo:listener];
[_connection send:stanza];
}
/*! @ignore
called when the object is retreived
@params aStanza the stanza containing the result
@params listener internal
*/
- (BOOL)_didReceiveObject:(TNStropheStanza)aStanza userInfo:(id)listener
{
if ([aStanza type] == @"result")
{
var dataString = [[aStanza firstChildWithName:listener.key] text];
// check if a an LPCrashReporter is here.
// and if yes deactive it during parsing
// data
try
{
if (dataString)
var obj = [CPKeyedUnarchiver unarchiveObjectWithData:[CPData dataWithRawString:TNStropheStripHTMLCharCode(dataString)]];
}
catch(ex)
{
[[CPNotificationCenter defaultCenter] postNotificationName:TNStrophePrivateStorageGetErrorNotification object:self userInfo:ex];
}
}
[listener.target performSelector:listener.selector withObject:aStanza withObject:obj];
return NO;
}
@end