Simplify default and support custom notifications for nodes.
[pithos-macos] / pithos-macos / PithosSharingAccountsNode.m
index 76868ce..f96b598 100644 (file)
@@ -2,7 +2,7 @@
 //  PithosAccountNode.m
 //  pithos-macos
 //
-// Copyright 2011 GRNET S.A. All rights reserved.
+// Copyright 2011-2012 GRNET S.A. All rights reserved.
 //
 // Redistribution and use in source and binary forms, with or
 // without modification, are permitted provided that the following
 #import "PithosSharingAccountsNode.h"
 #import "PithosAccountNode.h"
 #import "ASIPithosRequest.h"
+#import "ASIPithos.h"
 #import "ASIPithosAccount.h"
 #import "ASIDownloadCache.h"
-#import "PithosFileUtilities.h"
+#import "PithosUtilities.h"
+#import "PithosActivityFacility.h"
 
 @implementation PithosSharingAccountsNode
+@synthesize pithos;
 
 #pragma mark -
 #pragma mark Object Lifecycle
 
-- (id)init {
-    if ((self == [super init])) {
+- (id)initWithPithos:(ASIPithos *)aPithos {
+    if ((self = [super init])) {
+        self.pithos = aPithos;
         self.sharingAccount = @"";
     }
     return self;
     [sharingAccountsRequest clearDelegatesAndCancel];
     [sharingAccountsRequest release];
     [sharingAccounts release];
+    [pithos release];
     [super dealloc];
 }
 
 #pragma mark -
 #pragma mark Properties
 
+- (void)setPithos:(ASIPithos *)aPithos {
+    if (aPithos && ![aPithos isEqualTo:pithos]) {
+        [pithos release];
+        pithos = [aPithos retain];
+        [url release];
+        url = nil;
+    }
+}
+
 - (NSString *)url {
     if (url == nil) 
-        url = [[ASIPithosRequest storageURLPrefix] copy];
+        url = [pithos.storageURLPrefix copy];
     return url;
 }
 
                 break;
             case PithosNodeStateRefreshNeeded:
                 freshness = PithosNodeStateRefreshing;
-                sharingAccountsRequest = [[ASIPithosRequest listSharingAccountsRequestWithLimit:0 
-                                                                                         marker:nil] retain];
+                sharingAccountsRequest = [[ASIPithosRequest listSharingAccountsRequestWithPithos:pithos limit:0 marker:nil] retain];
                 sharingAccountsRequest.delegate = self;
-                sharingAccountsRequest.didFinishSelector = @selector(sharingAccountsRequestFinished:);
-                sharingAccountsRequest.didFailSelector = @selector(sharingAccountsRequestFailed:);
+                sharingAccountsRequest.didFinishSelector = @selector(performRequestFinishedDelegateInBackground:);
+                sharingAccountsRequest.didFailSelector = @selector(performRequestFailedDelegateInBackground:);
+                sharingAccountsRequest.userInfo = [NSMutableDictionary dictionaryWithObjectsAndKeys:
+                                                   [NSNumber numberWithInteger:NSOperationQueuePriorityVeryHigh], @"priority", 
+                                                   [NSNumber numberWithUnsignedInteger:10], @"retries", 
+                                                   NSStringFromSelector(@selector(sharingAccountsRequestFinished:)), @"didFinishSelector", 
+                                                   NSStringFromSelector(@selector(sharingAccountsRequestFailed:)), @"didFailSelector", 
+                                                   nil];
                 if (!forcedRefresh)
                     sharingAccountsRequest.downloadCache = [ASIDownloadCache sharedCache];
-                [sharingAccountsRequest startAsynchronous];
+                [[PithosUtilities prepareRequest:sharingAccountsRequest priority:NSOperationQueuePriorityVeryHigh] startAsynchronous];
                 break;
             case PithosNodeStateRefreshing:
                 break;
 #pragma mark -
 #pragma mark ASIHTTPRequestDelegate
 
-- (void)sharingAccountsRequestFinished:(ASIPithosRequest *)request {
-    NSLog(@"URL: %@", [sharingAccountsRequest url]);
-    NSLog(@"cached: %d", [sharingAccountsRequest didUseCachedResponse]);
-    
-    NSArray *someSharingAccounts = [sharingAccountsRequest sharingAccounts];
-    if (sharingAccounts == nil) {
-        sharingAccounts = [[NSMutableArray alloc] initWithArray:someSharingAccounts];
+- (void)sharingAccountsRequestFailed:(ASIPithosRequest *)request {
+    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
+    NSUInteger retries = [[sharingAccountsRequest.userInfo objectForKey:@"retries"] unsignedIntegerValue];
+    if (retries > 0) {
+        ASIPithosRequest *newSharingAccountsRequest = (ASIPithosRequest *)[PithosUtilities copyRequest:sharingAccountsRequest];
+        [(NSMutableDictionary *)(newSharingAccountsRequest.userInfo)setObject:[NSNumber numberWithUnsignedInteger:(--retries)] forKey:@"retries"];
+        [sharingAccountsRequest release];
+        sharingAccountsRequest = newSharingAccountsRequest;
+        [[PithosUtilities prepareRequest:sharingAccountsRequest priority:[[sharingAccountsRequest.userInfo objectForKey:@"priority"] integerValue]] startAsynchronous];
     } else {
-        [sharingAccounts addObjectsFromArray:someSharingAccounts];
-    }
-    if ([someSharingAccounts count] < 10000) {
-        if (!sharingAccountsRequest.didUseCachedResponse || ([sharingAccounts count] != [someSharingAccounts count]) || !children) {
-            // Save new children
-            NSLog(@"using newChildren");
-            newChildren = [[NSMutableArray alloc] init];
-            NSMutableIndexSet *keptNodes = [NSMutableIndexSet indexSet];
-            for (ASIPithosAccount *account in sharingAccounts) {
-                if (![account.name isEqualToString:[ASIPithosRequest authUser]]) {
-                    PithosAccountNode *node = [[[PithosAccountNode alloc] init] autorelease];
-                    node.parent = self;
-                    node.shared = shared;
-                    node.sharingAccount = account.name;
-                    if (children) {
-                        NSUInteger oldIndex = [children indexOfObject:node];
-                        if (oldIndex != NSNotFound) {
-                            // Use the same pointer value, if possible
-                            node = [children objectAtIndex:oldIndex];
-                            [keptNodes addIndex:oldIndex];
-                        }
-                    }
-                    [newChildren addObject:node];
-                }
-            }
-            [[children objectsAtIndexes:
-              [[NSIndexSet indexSetWithIndexesInRange:NSMakeRange(0, [children count])] indexesPassingTest:^(NSUInteger idx, BOOL *stop){
-                if ([keptNodes containsIndex:idx])
-                    return NO;
-                return YES;
-            }]] makeObjectsPerformSelector:@selector(pithosNodeWillBeRemoved)];
-        }
-        // Else cache was used and all results were fetched during this request, so existing children can be reused
+        NSString *message;
+        NSError *error = [sharingAccountsRequest error];
+        if (error)
+            message = [NSString stringWithFormat:@"Sharing accounts listing failed: %@", error];
+        else
+            message = [NSString stringWithFormat:@"Sharing accounts listing failed: (%d) %@", 
+                       sharingAccountsRequest.responseStatusCode, sharingAccountsRequest.responseStatusMessage];
+        dispatch_async(dispatch_get_main_queue(), ^{
+            [[PithosActivityFacility defaultPithosActivityFacility] startAndEndActivityWithType:PithosActivityOther message:message];
+        });
+        [newChildren release];
+        newChildren = nil;
         [sharingAccountsRequest release];
         sharingAccountsRequest = nil;
         [sharingAccounts release];
         sharingAccounts = nil;
         forcedRefresh = NO;
         @synchronized(self) {
-            freshness = PithosNodeStateRefreshFinished;
+            freshness = PithosNodeStateRefreshNeeded;
         }
-        // Notify observers that children are updated
-        [[NSNotificationCenter defaultCenter] postNotificationName:@"PithosSharingAccountsNodeChildrenUpdated" object:self];
-    } else {
-        [sharingAccountsRequest release];
-        // Do an additional request to fetch more objects
-        sharingAccountsRequest = [[ASIPithosRequest listSharingAccountsRequestWithLimit:0 
-                                                                                 marker:[[someSharingAccounts lastObject] name]] retain];
-        sharingAccountsRequest.delegate = self;
-        if (!forcedRefresh)
-            sharingAccountsRequest.downloadCache = [ASIDownloadCache sharedCache];
-        [sharingAccountsRequest startAsynchronous];
     }
+    [pool drain];
 }
 
-- (void)accountRequestFailed:(ASIPithosRequest *)request {
-    [PithosFileUtilities httpRequestErrorAlertWithRequest:request];
-    [newChildren release];
-    newChildren = nil;
-    [sharingAccountsRequest release];
-    sharingAccountsRequest = nil;
-    [sharingAccounts release];
-    sharingAccounts = nil;
-    forcedRefresh = NO;
-    @synchronized(self) {
-        freshness = PithosNodeStateRefreshNeeded;
+- (void)sharingAccountsRequestFinished:(ASIPithosRequest *)request {
+    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
+    NSLog(@"List sharing accounts finished: %@", [sharingAccountsRequest url]);
+    NSLog(@"Cached: %d", [sharingAccountsRequest didUseCachedResponse]);
+    if (sharingAccountsRequest.responseStatusCode == 200) {
+        NSArray *someSharingAccounts = [sharingAccountsRequest sharingAccounts];
+        if (sharingAccounts == nil) {
+            sharingAccounts = [[NSMutableArray alloc] initWithArray:someSharingAccounts];
+        } else {
+            [sharingAccounts addObjectsFromArray:someSharingAccounts];
+        }
+        if ([someSharingAccounts count] < 10000) {
+            if (!sharingAccountsRequest.didUseCachedResponse || ([sharingAccounts count] != [someSharingAccounts count]) || !children) {
+                // Save new children
+                NSLog(@"using newChildren");
+                newChildren = [[NSMutableArray alloc] init];
+                NSMutableIndexSet *keptNodes = [NSMutableIndexSet indexSet];
+                for (ASIPithosAccount *account in sharingAccounts) {
+                    if (![account.name isEqualToString:pithos.authUser]) {
+                        PithosAccountNode *node = [[[PithosAccountNode alloc] initWithPithos:pithos] autorelease];
+                        node.parent = self;
+                        node.shared = shared;
+                        node.sharingAccount = account.name;
+                        node.inheritChildrenUpdatedNotificationName = inheritChildrenUpdatedNotificationName;
+                        if (children) {
+                            NSUInteger oldIndex = [children indexOfObject:node];
+                            if (oldIndex != NSNotFound) {
+                                // Use the same pointer value, if possible
+                                node = [children objectAtIndex:oldIndex];
+                                [keptNodes addIndex:oldIndex];
+                            }
+                        }
+                        [newChildren addObject:node];
+                    }
+                }
+                [[children objectsAtIndexes:
+                  [[NSIndexSet indexSetWithIndexesInRange:NSMakeRange(0, [children count])] indexesPassingTest:^(NSUInteger idx, BOOL *stop){
+                    if ([keptNodes containsIndex:idx])
+                        return NO;
+                    return YES;
+                }]] makeObjectsPerformSelector:@selector(pithosNodeWillBeRemoved)];
+            }
+            // Else cache was used and all results were fetched during this request, so existing children can be reused
+            [sharingAccountsRequest release];
+            sharingAccountsRequest = nil;
+            [sharingAccounts release];
+            sharingAccounts = nil;
+            forcedRefresh = NO;
+            @synchronized(self) {
+                freshness = PithosNodeStateRefreshFinished;
+            }
+            [self postChildrenUpdatedNotificationName];
+        } else {
+            [sharingAccountsRequest release];
+            // Do an additional request to fetch more objects
+            sharingAccountsRequest = [[ASIPithosRequest listSharingAccountsRequestWithPithos:pithos 
+                                                                                       limit:0 
+                                                                                      marker:[[someSharingAccounts lastObject] name]] retain];
+            sharingAccountsRequest.delegate = self;
+            sharingAccountsRequest.didFinishSelector = @selector(performRequestFinishedDelegateInBackground:);
+            sharingAccountsRequest.didFailSelector = @selector(performRequestFailedDelegateInBackground:);
+            sharingAccountsRequest.userInfo = [NSMutableDictionary dictionaryWithObjectsAndKeys:
+                                               [NSNumber numberWithInteger:NSOperationQueuePriorityVeryHigh], @"priority", 
+                                               [NSNumber numberWithUnsignedInteger:10], @"retries", 
+                                               NSStringFromSelector(@selector(sharingAccountsRequestFinished:)), @"didFinishSelector", 
+                                               NSStringFromSelector(@selector(sharingAccountsRequestFailed:)), @"didFailSelector", 
+                                               nil];
+            if (!forcedRefresh)
+                sharingAccountsRequest.downloadCache = [ASIDownloadCache sharedCache];
+            [[PithosUtilities prepareRequest:sharingAccountsRequest priority:NSOperationQueuePriorityVeryHigh] startAsynchronous];
+        }
+    } else {
+        [self sharingAccountsRequestFailed:sharingAccountsRequest];
     }
+    [pool drain];
 }
 
 @end