5 // Copyright 2011-2013 GRNET S.A. All rights reserved.
7 // Redistribution and use in source and binary forms, with or
8 // without modification, are permitted provided that the following
11 // 1. Redistributions of source code must retain the above
12 // copyright notice, this list of conditions and the following
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.
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.
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.
38 #import "PithosSharingAccountsNode.h"
39 #import "PithosAccountNode.h"
40 #import "ASIPithosRequest.h"
42 #import "ASIPithosAccount.h"
43 #import "ASIDownloadCache.h"
44 #import "PithosAccount.h"
45 #import "PithosUtilities.h"
46 #import "PithosActivityFacility.h"
48 @implementation PithosSharingAccountsNode
49 @synthesize sharingAccountsRequest;
52 #pragma mark Object Lifecycle
54 - (id)initWithPithosAccountManager:(PithosAccount *)aPithosAccountManager {
55 if ((self = [super initWithPithosAccountManager:aPithosAccountManager])) {
56 self.sharingAccount = @"";
62 [sharingAccountsRequest clearDelegatesAndCancel];
69 [sharingAccountsRequest clearDelegatesAndCancel];
70 self.sharingAccountsRequest = nil;
73 freshness = PithosNodeStateRefreshNeeded;
75 [self postChildrenUpdatedNotificationName];
80 #pragma mark Properties
83 return @"@sharing accounts@";
86 - (NSArray *)children {
89 case PithosNodeStateFresh:
91 case PithosNodeStateRefreshNeeded:
92 freshness = PithosNodeStateRefreshing;
93 self.sharingAccountsRequest = [ASIPithosRequest listSharingAccountsRequestWithPithos:pithosAccountManager.pithos limit:0 marker:nil];
94 sharingAccountsRequest.delegate = self;
95 sharingAccountsRequest.didFinishSelector = @selector(performRequestFinishedDelegateInBackground:);
96 sharingAccountsRequest.didFailSelector = @selector(performRequestFailedDelegateInBackground:);
97 sharingAccountsRequest.userInfo = [NSMutableDictionary dictionaryWithObjectsAndKeys:
98 [NSNumber numberWithInteger:NSOperationQueuePriorityVeryHigh], @"priority",
99 [NSNumber numberWithUnsignedInteger:10], @"retries",
100 NSStringFromSelector(@selector(sharingAccountsRequestFinished:)), @"didFinishSelector",
101 NSStringFromSelector(@selector(sharingAccountsRequestFailed:)), @"didFailSelector",
103 // if (!forcedRefresh)
104 // sharingAccountsRequest.downloadCache = [ASIDownloadCache sharedCache];
105 [[PithosUtilities prepareRequest:sharingAccountsRequest priority:NSOperationQueuePriorityVeryHigh] startAsynchronous];
107 case PithosNodeStateRefreshing:
109 case PithosNodeStateRefreshFinished:
111 children = newChildren;
114 freshness = PithosNodeStateFresh;
122 - (NSString *)displayName {
123 if (displayName == nil)
124 return @"sharing accounts";
125 return [displayName copy];
129 #pragma mark ASIHTTPRequestDelegate
131 - (void)sharingAccountsRequestFailed:(ASIPithosRequest *)request {
134 NSError *error = [sharingAccountsRequest error];
136 message = [NSString stringWithFormat:@"Sharing accounts listing %@ failed: %@",
137 sharingAccountsRequest.url, [error localizedDescription]];
139 message = [NSString stringWithFormat:@"Sharing accounts listing %@ failed: (%d) %@",
140 sharingAccountsRequest.url, sharingAccountsRequest.responseStatusCode, sharingAccountsRequest.responseStatusMessage];
141 dispatch_async(dispatch_get_main_queue(), ^{
142 [[PithosActivityFacility defaultPithosActivityFacility] startAndEndActivityWithType:PithosActivityOther message:message];
144 NSUInteger retries = [[sharingAccountsRequest.userInfo objectForKey:@"retries"] unsignedIntegerValue];
146 ASIPithosRequest *newSharingAccountsRequest = (ASIPithosRequest *)[PithosUtilities retryWithUpdatedURLRequest:sharingAccountsRequest
147 andPithosAccountManager:pithosAccountManager];;
148 [(NSMutableDictionary *)(newSharingAccountsRequest.userInfo)setObject:[NSNumber numberWithUnsignedInteger:(--retries)] forKey:@"retries"];
149 self.sharingAccountsRequest = newSharingAccountsRequest;
150 [[PithosUtilities prepareRequest:sharingAccountsRequest priority:[[sharingAccountsRequest.userInfo objectForKey:@"priority"] integerValue]] startAsynchronous];
153 self.sharingAccountsRequest = nil;
155 @synchronized(self) {
156 freshness = PithosNodeStateRefreshNeeded;
162 - (void)sharingAccountsRequestFinished:(ASIPithosRequest *)request {
164 DLog(@"List sharing accounts finished: %@", [sharingAccountsRequest url]);
165 DLog(@"Cached: %d", [sharingAccountsRequest didUseCachedResponse]);
166 if (sharingAccountsRequest.responseStatusCode == 200) {
167 NSMutableArray *sharingAccounts = [sharingAccountsRequest.userInfo objectForKey:@"sharingAccounts"];
168 NSArray *someSharingAccounts = [sharingAccountsRequest sharingAccounts];
169 if (sharingAccounts == nil) {
170 sharingAccounts = [NSMutableArray arrayWithArray:someSharingAccounts];
172 [sharingAccounts addObjectsFromArray:someSharingAccounts];
174 if ([someSharingAccounts count] < 10000) {
175 if (!sharingAccountsRequest.didUseCachedResponse || ([sharingAccounts count] != [someSharingAccounts count]) || !children) {
177 DLog(@"using newChildren");
178 newChildren = [[NSMutableArray alloc] init];
179 NSMutableIndexSet *keptNodes = [NSMutableIndexSet indexSet];
180 for (ASIPithosAccount *account in sharingAccounts) {
181 if (![account.name isEqualToString:pithosAccountManager.pithos.authUser]) {
182 PithosAccountNode *node = [[PithosAccountNode alloc] initWithPithosAccountManager:pithosAccountManager];
184 node.shared = shared;
185 node.sharingAccount = account.name;
186 node.inheritChildrenUpdatedNotificationName = inheritChildrenUpdatedNotificationName;
188 NSUInteger oldIndex = [children indexOfObject:node];
189 if (oldIndex != NSNotFound) {
190 // Use the same pointer value, if possible
191 node = [children objectAtIndex:oldIndex];
192 [keptNodes addIndex:oldIndex];
195 [newChildren addObject:node];
198 [[children objectsAtIndexes:
199 [[NSIndexSet indexSetWithIndexesInRange:NSMakeRange(0, [children count])] indexesPassingTest:^(NSUInteger idx, BOOL *stop){
200 if ([keptNodes containsIndex:idx])
203 }]] makeObjectsPerformSelector:@selector(pithosNodeWillBeRemoved)];
205 // Else cache was used and all results were fetched during this request, so existing children can be reused
206 // Update user catalog even if cache was used
207 NSMutableArray *sharingAccountsNames = [NSMutableArray arrayWithCapacity:sharingAccounts.count];
208 for (ASIPithosAccount *account in sharingAccounts) {
209 [sharingAccountsNames addObject:account.name];
211 [pithosAccountManager updateUserCatalogForDisplaynames:nil UUIDs:sharingAccountsNames];
212 self.sharingAccountsRequest = nil;
214 @synchronized(self) {
215 freshness = PithosNodeStateRefreshFinished;
217 [self postChildrenUpdatedNotificationName];
219 // Do an additional request to fetch more objects
220 self.sharingAccountsRequest = [ASIPithosRequest listSharingAccountsRequestWithPithos:pithosAccountManager.pithos
222 marker:[[someSharingAccounts lastObject] name]];
223 sharingAccountsRequest.delegate = self;
224 sharingAccountsRequest.didFinishSelector = @selector(performRequestFinishedDelegateInBackground:);
225 sharingAccountsRequest.didFailSelector = @selector(performRequestFailedDelegateInBackground:);
226 sharingAccountsRequest.userInfo = [NSMutableDictionary dictionaryWithObjectsAndKeys:
227 [NSNumber numberWithInteger:NSOperationQueuePriorityVeryHigh], @"priority",
228 [NSNumber numberWithUnsignedInteger:10], @"retries",
229 NSStringFromSelector(@selector(sharingAccountsRequestFinished:)), @"didFinishSelector",
230 NSStringFromSelector(@selector(sharingAccountsRequestFailed:)), @"didFailSelector",
231 sharingAccounts, @"sharingAccounts",
233 // if (!forcedRefresh)
234 // sharingAccountsRequest.downloadCache = [ASIDownloadCache sharedCache];
235 [[PithosUtilities prepareRequest:sharingAccountsRequest priority:NSOperationQueuePriorityVeryHigh] startAsynchronous];
238 [self sharingAccountsRequestFailed:sharingAccountsRequest];