Improve handling of node requests
[pithos-macos] / pithos-macos / PithosAccountNode.m
index 51b5c61..329b610 100644 (file)
@@ -49,7 +49,7 @@
 static NSImage *sharedIcon = nil;
 
 @implementation PithosAccountNode
-@synthesize pithos, pithosAccount, translatedGroups;
+@synthesize pithos, pithosAccount, accountRequest, applyMetadataAccountRequest, refreshMetadataAccountRequest, translatedGroups;
 
 + (void)initialize {
        if (self == [PithosAccountNode class])
@@ -73,6 +73,37 @@ static NSImage *sharedIcon = nil;
 }
 
 #pragma mark -
+#pragma mark Internal
+
+- (void)updateGroups {
+    if (!pithosAccount) {
+        self.translatedGroups = [NSMutableDictionary dictionary];
+    } else if (pithosAccountManager) {
+        NSMutableSet *UUIDs = [NSMutableSet set];
+        for (NSString *groupName in pithosAccount.groups) {
+            [UUIDs addObjectsFromArray:[pithosAccount.groups objectForKey:groupName]];
+        }
+        [UUIDs removeObject:@""];
+        [UUIDs removeObject:@"*"];
+        if (UUIDs.count) {
+            [pithosAccountManager updateUserCatalogForForDisplaynames:nil UUIDs:[UUIDs allObjects]];
+        }
+        
+        NSMutableDictionary *newTranslatedGroups = [NSMutableDictionary dictionaryWithCapacity:pithosAccount.groups.count];
+        for (NSString *groupName in pithosAccount.groups) {
+            NSMutableArray *groupUsers = [NSMutableArray array];
+            for (NSString *UUID in [pithosAccount.groups objectForKey:groupName]) {
+                [groupUsers addObject:[pithosAccountManager displaynameForUUID:UUID safe:YES]];
+            }
+            [newTranslatedGroups setObject:groupUsers forKey:groupName];
+        }
+        self.translatedGroups = newTranslatedGroups;
+    } else {
+        self.translatedGroups = [pithosAccount.groups copy];
+    }
+}
+
+#pragma mark -
 #pragma mark Properties
 
 - (void)setPithos:(ASIPithos *)aPithos {
@@ -80,42 +111,19 @@ static NSImage *sharedIcon = nil;
         pithos = aPithos;
         url = nil;
         [accountRequest clearDelegatesAndCancel];
-        accountRequest = nil;
+        self.accountRequest = nil;
         [refreshMetadataAccountRequest clearDelegatesAndCancel];
-        refreshMetadataAccountRequest = nil;
+        self.refreshMetadataAccountRequest = nil;
         [applyMetadataAccountRequest clearDelegatesAndCancel];
-        applyMetadataAccountRequest = nil;
+        self.applyMetadataAccountRequest = nil;
         reset = YES;
     }
 }
 
 - (void)setPithosAccount:(ASIPithosAccount *)aPithosAccount {
-    if (!aPithosAccount) {
+    if (![pithosAccount isEqualTo:aPithosAccount]) {
         pithosAccount = aPithosAccount;
-        self.translatedGroups = [NSMutableDictionary dictionary];
-    } else if (![aPithosAccount isEqualTo:pithosAccount]) {
-        pithosAccount = aPithosAccount;
-        if (pithosAccountManager) {
-            NSMutableArray *UUIDs = [NSMutableArray array];
-            for (NSString *groupName in pithosAccount.groups) {
-                [UUIDs addObjectsFromArray:[pithosAccount.groups objectForKey:groupName]];
-            }
-            if (UUIDs.count) {
-                [pithosAccountManager updateUserCatalogForForDisplaynames:nil UUIDs:UUIDs];
-            }
-            
-            NSMutableDictionary *newTranslatedGroups = [NSMutableDictionary dictionaryWithCapacity:pithosAccount.groups.count];
-            for (NSString *groupName in pithosAccount.groups) {
-                NSMutableArray *groupUsers = [NSMutableArray array];
-                for (NSString *UUID in [pithosAccount.groups objectForKey:groupName]) {
-                    [groupUsers addObject:[pithosAccountManager displaynameForUUID:UUID safe:YES]];
-                }
-                [newTranslatedGroups setObject:groupUsers forKey:groupName];
-            }
-            self.translatedGroups = newTranslatedGroups;
-        } else {
-            self.translatedGroups = [pithosAccount.groups copy];
-        }
+        [self updateGroups];
     }
 }
 
@@ -131,11 +139,11 @@ static NSImage *sharedIcon = nil;
     @synchronized(self) {
         if (reset) {
             [accountRequest clearDelegatesAndCancel];
-            accountRequest = nil;
+            self.accountRequest = nil;
             [refreshMetadataAccountRequest clearDelegatesAndCancel];
-            refreshMetadataAccountRequest = nil;
+            self.refreshMetadataAccountRequest = nil;
             [applyMetadataAccountRequest clearDelegatesAndCancel];
-            applyMetadataAccountRequest = nil;
+            self.applyMetadataAccountRequest = nil;
             children = nil;
             newChildren = nil;
             self.pithosAccount = nil;
@@ -149,11 +157,11 @@ static NSImage *sharedIcon = nil;
                 break;
             case PithosNodeStateRefreshNeeded:
                 freshness = PithosNodeStateRefreshing;
-                accountRequest = [ASIPithosAccountRequest listContainersRequestWithPithos:pithos 
-                                                                                     limit:0 
-                                                                                    marker:nil 
-                                                                                    shared:shared 
-                                                                                     until:nil];
+                self.accountRequest = [ASIPithosAccountRequest listContainersRequestWithPithos:pithos
+                                                                                         limit:0
+                                                                                        marker:nil
+                                                                                        shared:shared
+                                                                                         until:nil];
                 if (sharingAccount)
                     [accountRequest setRequestUserFromDefaultTo:sharingAccount withPithos:pithos];
                 else if (!forcedRefresh)
@@ -185,8 +193,15 @@ static NSImage *sharedIcon = nil;
 }
 
 - (NSString *)displayName {
-    if (displayName == nil)
-        return [NSString stringWithString:(sharingAccount ? sharingAccount : @"account")];
+    if (displayName == nil) {
+        if (!sharingAccount) {
+            return @"account";
+        } else if (pithosAccountManager) {
+            return [pithosAccountManager displaynameForUUID:sharingAccount safe:YES];
+        } else {
+            return [sharingAccount copy];
+        }
+    }
     return [displayName copy];
 }
 
@@ -215,12 +230,11 @@ static NSImage *sharedIcon = nil;
         if (retries > 0) {
             ASIPithosAccountRequest *newAccountRequest = (ASIPithosAccountRequest *)[PithosUtilities copyRequest:accountRequest];
             [(NSMutableDictionary *)(newAccountRequest.userInfo)setObject:[NSNumber numberWithUnsignedInteger:(--retries)] forKey:@"retries"];
-            accountRequest = newAccountRequest;
+            self.accountRequest = newAccountRequest;
             [[PithosUtilities prepareRequest:accountRequest priority:[[accountRequest.userInfo objectForKey:@"priority"] integerValue]] startAsynchronous];
         } else {
             newChildren = nil;
-            accountRequest = nil;
-            containers = nil;
+            self.accountRequest = nil;
             forcedRefresh = NO;
             @synchronized(self) {
                 freshness = PithosNodeStateRefreshNeeded;
@@ -236,9 +250,10 @@ static NSImage *sharedIcon = nil;
         if (accountRequest.responseStatusCode == 200) {
             self.pithosAccount = [accountRequest account];
             
+            NSMutableArray *containers = [accountRequest.userInfo objectForKey:@"containers"];
             NSArray *someContainers = [accountRequest containers];
             if (containers == nil) {
-                containers = [[NSMutableArray alloc] initWithArray:someContainers];
+                containers = [NSMutableArray arrayWithArray:someContainers];
             } else {
                 [containers addObjectsFromArray:someContainers];
             }
@@ -254,6 +269,7 @@ static NSImage *sharedIcon = nil;
                         node.shared = shared;
                         node.sharingAccount = sharingAccount;
                         node.inheritChildrenUpdatedNotificationName = inheritChildrenUpdatedNotificationName;
+                        node.pithosAccountManager = pithosAccountManager;
                         if (children) {
                             NSUInteger oldIndex = [children indexOfObject:node];
                             if (oldIndex != NSNotFound) {
@@ -274,8 +290,7 @@ static NSImage *sharedIcon = nil;
                     }]] makeObjectsPerformSelector:@selector(pithosNodeWillBeRemoved)];
                 }
                 // Else cache was used and all results were fetched during this request, so existing children can be reused
-                accountRequest = nil;
-                containers = nil;
+                self.accountRequest = nil;
                 forcedRefresh = NO;
                 @synchronized(self) {
                     freshness = PithosNodeStateRefreshFinished;
@@ -283,11 +298,11 @@ static NSImage *sharedIcon = nil;
                 [self postChildrenUpdatedNotificationName];
             } else {
                 // Do an additional request to fetch more objects
-                accountRequest = [ASIPithosAccountRequest listContainersRequestWithPithos:pithos 
-                                                                                     limit:0 
-                                                                                    marker:[[someContainers lastObject] name] 
-                                                                                    shared:shared 
-                                                                                     until:nil];
+                self.accountRequest = [ASIPithosAccountRequest listContainersRequestWithPithos:pithos
+                                                                                         limit:0
+                                                                                        marker:[[someContainers lastObject] name]
+                                                                                        shared:shared
+                                                                                         until:nil];
                 if (sharingAccount)
                     [accountRequest setRequestUserFromDefaultTo:sharingAccount withPithos:pithos];
                 else if (!forcedRefresh)
@@ -299,14 +314,14 @@ static NSImage *sharedIcon = nil;
                                            [NSNumber numberWithInteger:NSOperationQueuePriorityVeryHigh], @"priority", 
                                            [NSNumber numberWithUnsignedInteger:10], @"retries", 
                                            NSStringFromSelector(@selector(accountRequestFinished:)), @"didFinishSelector", 
-                                           NSStringFromSelector(@selector(accountRequestFailed:)), @"didFailSelector", 
+                                           NSStringFromSelector(@selector(accountRequestFailed:)), @"didFailSelector",
+                                           containers, @"containers",
                                            nil];
                 [[PithosUtilities prepareRequest:accountRequest priority:NSOperationQueuePriorityVeryHigh] startAsynchronous];
             }
         } else if (accountRequest.responseStatusCode == 304) {
             // Account is not modified, so existing children can be reused
-            accountRequest = nil;
-            containers = nil;
+            self.accountRequest = nil;
             forcedRefresh = NO;
             @synchronized(self) {
                 freshness = PithosNodeStateRefreshFinished;
@@ -325,13 +340,13 @@ static NSImage *sharedIcon = nil;
         
         if ([request isEqualTo:applyMetadataAccountRequest]) {
             @synchronized(self) {
-                applyMetadataAccountRequest = nil;
+                self.applyMetadataAccountRequest = nil;
             }
             [self refreshInfo];
         } else if ([request isEqualTo:refreshMetadataAccountRequest]) {
             self.pithosAccount = [refreshMetadataAccountRequest account];
             @synchronized(self) {
-                refreshMetadataAccountRequest = nil;
+                self.refreshMetadataAccountRequest = nil;
             }
         }
     }
@@ -345,11 +360,11 @@ static NSImage *sharedIcon = nil;
             [(NSMutableDictionary *)(newRequest.userInfo)setObject:[NSNumber numberWithUnsignedInteger:(--retries)] forKey:@"retries"];
             if ([request isEqualTo:applyMetadataAccountRequest]) {
                 @synchronized(self) {
-                    applyMetadataAccountRequest = newRequest;
+                    self.applyMetadataAccountRequest = newRequest;
                 }
             } else if ([request isEqualTo:refreshMetadataAccountRequest]) {
                 @synchronized(self) {
-                    refreshMetadataAccountRequest = newRequest;
+                    self.refreshMetadataAccountRequest = newRequest;
                 }
             }
             [[PithosUtilities prepareRequest:newRequest priority:[[newRequest.userInfo objectForKey:@"priority"] integerValue]] startAsynchronous];
@@ -357,12 +372,12 @@ static NSImage *sharedIcon = nil;
             if ([request isEqualTo:applyMetadataAccountRequest]) {
                 [PithosUtilities httpRequestErrorAlertWithRequest:applyMetadataAccountRequest];
                 @synchronized(self) {
-                    applyMetadataAccountRequest = nil;
+                    self.applyMetadataAccountRequest = nil;
                 }
             } else if ([request isEqualTo:refreshMetadataAccountRequest]) {
                 [PithosUtilities httpRequestErrorAlertWithRequest:refreshMetadataAccountRequest];
                 @synchronized(self) {
-                    refreshMetadataAccountRequest = nil;
+                    self.refreshMetadataAccountRequest = nil;
                 }
             }
         }
@@ -410,7 +425,7 @@ static NSImage *sharedIcon = nil;
                                 }
                             }
                             if (!inexistentGroupUsers.count) {
-                                // create groups
+                                // Create groups.
                                 for (NSString *groupName in translatedGroups) {
                                     NSMutableArray *groupUsers = [NSMutableArray array];
                                     for (NSString *groupUser in [translatedGroups objectForKey:groupName]) {
@@ -453,7 +468,14 @@ static NSImage *sharedIcon = nil;
                             }
                         }
                     } else {
-                        [groups setObject:[NSArray arrayWithObject:@""] forKey:@"group"];
+                        for (NSString *groupName in translatedGroups) {
+                            if ([[translatedGroups objectForKey:groupName] containsObject:@"*"]) {
+                                [groups setObject:[NSMutableArray arrayWithObject:@"*"] forKey:groupName];
+                            }
+                        }
+                        if (!groups.count) {
+                            [groups setObject:[NSArray arrayWithObject:@""] forKey:@"group"];
+                        }
                     }
                 } else {
                     [groups addEntriesFromDictionary:translatedGroups];
@@ -462,10 +484,10 @@ static NSImage *sharedIcon = nil;
                 [groups setObject:[NSArray arrayWithObject:@""] forKey:@"group"];
             }
             
-            applyMetadataAccountRequest = [ASIPithosAccountRequest updateAccountMetadataRequestWithPithos:pithos
-                                                                                                    groups:groups 
-                                                                                                  metadata:pithosAccount.metadata 
-                                                                                                    update:NO];
+            self.applyMetadataAccountRequest = [ASIPithosAccountRequest updateAccountMetadataRequestWithPithos:pithos
+                                                                                                        groups:groups
+                                                                                                      metadata:pithosAccount.metadata
+                                                                                                        update:NO];
             applyMetadataAccountRequest.delegate = self;
             applyMetadataAccountRequest.didFinishSelector = @selector(performRequestFinishedDelegateInBackground:);
             applyMetadataAccountRequest.didFailSelector = @selector(performRequestFailedDelegateInBackground:);
@@ -483,7 +505,7 @@ static NSImage *sharedIcon = nil;
 - (void)refreshInfo {
     @synchronized(self) {
         if (refreshMetadataAccountRequest == nil) {
-            refreshMetadataAccountRequest = [ASIPithosAccountRequest accountMetadataRequestWithPithos:pithos];
+            self.refreshMetadataAccountRequest = [ASIPithosAccountRequest accountMetadataRequestWithPithos:pithos];
             refreshMetadataAccountRequest.delegate = self;
             refreshMetadataAccountRequest.didFinishSelector = @selector(performRequestFinishedDelegateInBackground:);
             refreshMetadataAccountRequest.didFailSelector = @selector(performRequestFailedDelegateInBackground:);