Statistics
| Branch: | Tag: | Revision:

root / pithos-macos / PithosSharingAccountsNode.m @ 7da4ebcc

History | View | Annotate | Download (11.4 kB)

1
//
2
//  PithosAccountNode.m
3
//  pithos-macos
4
//
5
// Copyright 2011-2012 GRNET S.A. All rights reserved.
6
//
7
// Redistribution and use in source and binary forms, with or
8
// without modification, are permitted provided that the following
9
// conditions are met:
10
// 
11
//   1. Redistributions of source code must retain the above
12
//      copyright notice, this list of conditions and the following
13
//      disclaimer.
14
// 
15
//   2. Redistributions in binary form must reproduce the above
16
//      copyright notice, this list of conditions and the following
17
//      disclaimer in the documentation and/or other materials
18
//      provided with the distribution.
19
// 
20
// THIS SOFTWARE IS PROVIDED BY GRNET S.A. ``AS IS'' AND ANY EXPRESS
21
// OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
22
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
23
// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GRNET S.A OR
24
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
25
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
26
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
27
// USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
28
// AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29
// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
30
// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
31
// POSSIBILITY OF SUCH DAMAGE.
32
// 
33
// The views and conclusions contained in the software and
34
// documentation are those of the authors and should not be
35
// interpreted as representing official policies, either expressed
36
// or implied, of GRNET S.A.
37

    
38
#import "PithosSharingAccountsNode.h"
39
#import "PithosAccountNode.h"
40
#import "ASIPithosRequest.h"
41
#import "ASIPithos.h"
42
#import "ASIPithosAccount.h"
43
#import "ASIDownloadCache.h"
44
#import "PithosUtilities.h"
45
#import "PithosActivityFacility.h"
46

    
47
@implementation PithosSharingAccountsNode
48
@synthesize pithos;
49

    
50
#pragma mark -
51
#pragma mark Object Lifecycle
52

    
53
- (id)initWithPithos:(ASIPithos *)aPithos {
54
    if ((self = [super init])) {
55
        self.pithos = aPithos;
56
        self.sharingAccount = @"";
57
        self.childrenUpdatedNotificationName = [NSString stringWithString:@"PithosSharingAccountsNodeChildrenUpdated"];
58
    }
59
    return self;
60
}
61

    
62
- (void)dealloc {
63
    [sharingAccountsRequest clearDelegatesAndCancel];
64
    [sharingAccountsRequest release];
65
    [sharingAccounts release];
66
    [pithos release];
67
    [super dealloc];
68
}
69

    
70
#pragma mark -
71
#pragma mark Properties
72

    
73
- (void)setPithos:(ASIPithos *)aPithos {
74
    if (aPithos && ![aPithos isEqualTo:pithos]) {
75
        [pithos release];
76
        pithos = [aPithos retain];
77
        [url release];
78
        url = nil;
79
    }
80
}
81

    
82
- (NSString *)url {
83
    if (url == nil) 
84
        url = [pithos.storageURLPrefix copy];
85
    return url;
86
}
87

    
88
- (NSArray *)children {
89
    @synchronized(self) {
90
        switch (freshness) {
91
            case PithosNodeStateFresh:
92
                break;
93
            case PithosNodeStateRefreshNeeded:
94
                freshness = PithosNodeStateRefreshing;
95
                sharingAccountsRequest = [[ASIPithosRequest listSharingAccountsRequestWithPithos:pithos limit:0 marker:nil] retain];
96
                sharingAccountsRequest.delegate = self;
97
                sharingAccountsRequest.didFinishSelector = @selector(performRequestFinishedDelegateInBackground:);
98
                sharingAccountsRequest.didFailSelector = @selector(performRequestFailedDelegateInBackground:);
99
                sharingAccountsRequest.userInfo = [NSMutableDictionary dictionaryWithObjectsAndKeys:
100
                                                   [NSNumber numberWithInteger:NSOperationQueuePriorityVeryHigh], @"priority", 
101
                                                   [NSNumber numberWithUnsignedInteger:10], @"retries", 
102
                                                   NSStringFromSelector(@selector(sharingAccountsRequestFinished:)), @"didFinishSelector", 
103
                                                   NSStringFromSelector(@selector(sharingAccountsRequestFailed:)), @"didFailSelector", 
104
                                                   nil];
105
                if (!forcedRefresh)
106
                    sharingAccountsRequest.downloadCache = [ASIDownloadCache sharedCache];
107
                [[PithosUtilities prepareRequest:sharingAccountsRequest priority:NSOperationQueuePriorityVeryHigh] startAsynchronous];
108
                break;
109
            case PithosNodeStateRefreshing:
110
                break;
111
            case PithosNodeStateRefreshFinished:
112
                if (newChildren) {
113
                    [children release];
114
                    children = newChildren;
115
                    newChildren = nil;
116
                }
117
                freshness = PithosNodeStateFresh;
118
            default:
119
                break;
120
        }
121
        return children;
122
    }
123
}
124

    
125
- (NSString *)displayName {
126
    if (displayName == nil)
127
        return [NSString stringWithString:@"sharing accounts"];
128
    return [[displayName copy] autorelease];
129
}
130

    
131
#pragma mark -
132
#pragma mark ASIHTTPRequestDelegate
133

    
134
- (void)sharingAccountsRequestFailed:(ASIPithosRequest *)request {
135
    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
136
    NSUInteger retries = [[sharingAccountsRequest.userInfo objectForKey:@"retries"] unsignedIntegerValue];
137
    if (retries > 0) {
138
        ASIPithosRequest *newSharingAccountsRequest = (ASIPithosRequest *)[PithosUtilities copyRequest:sharingAccountsRequest];
139
        [(NSMutableDictionary *)(newSharingAccountsRequest.userInfo)setObject:[NSNumber numberWithUnsignedInteger:(--retries)] forKey:@"retries"];
140
        [sharingAccountsRequest release];
141
        sharingAccountsRequest = newSharingAccountsRequest;
142
        [[PithosUtilities prepareRequest:sharingAccountsRequest priority:[[sharingAccountsRequest.userInfo objectForKey:@"priority"] integerValue]] startAsynchronous];
143
    } else {
144
        NSString *message;
145
        NSError *error = [sharingAccountsRequest error];
146
        if (error)
147
            message = [NSString stringWithFormat:@"Sharing accounts listing failed: %@", error];
148
        else
149
            message = [NSString stringWithFormat:@"Sharing accounts listing failed: (%d) %@", 
150
                       sharingAccountsRequest.responseStatusCode, sharingAccountsRequest.responseStatusMessage];
151
        dispatch_async(dispatch_get_main_queue(), ^{
152
            [[PithosActivityFacility defaultPithosActivityFacility] startAndEndActivityWithType:PithosActivityOther message:message];
153
        });
154
        [newChildren release];
155
        newChildren = nil;
156
        [sharingAccountsRequest release];
157
        sharingAccountsRequest = nil;
158
        [sharingAccounts release];
159
        sharingAccounts = nil;
160
        forcedRefresh = NO;
161
        @synchronized(self) {
162
            freshness = PithosNodeStateRefreshNeeded;
163
        }
164
    }
165
    [pool drain];
166
}
167

    
168
- (void)sharingAccountsRequestFinished:(ASIPithosRequest *)request {
169
    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
170
    NSLog(@"List sharing accounts finished: %@", [sharingAccountsRequest url]);
171
    NSLog(@"Cached: %d", [sharingAccountsRequest didUseCachedResponse]);
172
    if (sharingAccountsRequest.responseStatusCode == 200) {
173
        NSArray *someSharingAccounts = [sharingAccountsRequest sharingAccounts];
174
        if (sharingAccounts == nil) {
175
            sharingAccounts = [[NSMutableArray alloc] initWithArray:someSharingAccounts];
176
        } else {
177
            [sharingAccounts addObjectsFromArray:someSharingAccounts];
178
        }
179
        if ([someSharingAccounts count] < 10000) {
180
            if (!sharingAccountsRequest.didUseCachedResponse || ([sharingAccounts count] != [someSharingAccounts count]) || !children) {
181
                // Save new children
182
                NSLog(@"using newChildren");
183
                newChildren = [[NSMutableArray alloc] init];
184
                NSMutableIndexSet *keptNodes = [NSMutableIndexSet indexSet];
185
                for (ASIPithosAccount *account in sharingAccounts) {
186
                    if (![account.name isEqualToString:pithos.authUser]) {
187
                        PithosAccountNode *node = [[[PithosAccountNode alloc] init] autorelease];
188
                        node.parent = self;
189
                        node.shared = shared;
190
                        node.sharingAccount = account.name;
191
                        if (children) {
192
                            NSUInteger oldIndex = [children indexOfObject:node];
193
                            if (oldIndex != NSNotFound) {
194
                                // Use the same pointer value, if possible
195
                                node = [children objectAtIndex:oldIndex];
196
                                [keptNodes addIndex:oldIndex];
197
                            }
198
                        }
199
                        [newChildren addObject:node];
200
                    }
201
                }
202
                [[children objectsAtIndexes:
203
                  [[NSIndexSet indexSetWithIndexesInRange:NSMakeRange(0, [children count])] indexesPassingTest:^(NSUInteger idx, BOOL *stop){
204
                    if ([keptNodes containsIndex:idx])
205
                        return NO;
206
                    return YES;
207
                }]] makeObjectsPerformSelector:@selector(pithosNodeWillBeRemoved)];
208
            }
209
            // Else cache was used and all results were fetched during this request, so existing children can be reused
210
            [sharingAccountsRequest release];
211
            sharingAccountsRequest = nil;
212
            [sharingAccounts release];
213
            sharingAccounts = nil;
214
            forcedRefresh = NO;
215
            @synchronized(self) {
216
                freshness = PithosNodeStateRefreshFinished;
217
            }
218
            if (childrenUpdatedNotificationName) {
219
                // Notify observers that children are updated
220
                [[NSNotificationCenter defaultCenter] postNotificationName:childrenUpdatedNotificationName object:self];
221
            }
222
        } else {
223
            [sharingAccountsRequest release];
224
            // Do an additional request to fetch more objects
225
            sharingAccountsRequest = [[ASIPithosRequest listSharingAccountsRequestWithPithos:pithos 
226
                                                                                       limit:0 
227
                                                                                      marker:[[someSharingAccounts lastObject] name]] retain];
228
            sharingAccountsRequest.delegate = self;
229
            sharingAccountsRequest.didFinishSelector = @selector(performRequestFinishedDelegateInBackground:);
230
            sharingAccountsRequest.didFailSelector = @selector(performRequestFailedDelegateInBackground:);
231
            sharingAccountsRequest.userInfo = [NSMutableDictionary dictionaryWithObjectsAndKeys:
232
                                               [NSNumber numberWithInteger:NSOperationQueuePriorityVeryHigh], @"priority", 
233
                                               [NSNumber numberWithUnsignedInteger:10], @"retries", 
234
                                               NSStringFromSelector(@selector(sharingAccountsRequestFinished:)), @"didFinishSelector", 
235
                                               NSStringFromSelector(@selector(sharingAccountsRequestFailed:)), @"didFailSelector", 
236
                                               nil];
237
            if (!forcedRefresh)
238
                sharingAccountsRequest.downloadCache = [ASIDownloadCache sharedCache];
239
            [[PithosUtilities prepareRequest:sharingAccountsRequest priority:NSOperationQueuePriorityVeryHigh] startAsynchronous];
240
        }
241
    } else {
242
        [self sharingAccountsRequestFailed:sharingAccountsRequest];
243
    }
244
    [pool drain];
245
}
246

    
247
@end