// // PithosAccountNode.m // pithos-macos // // Copyright 2011 GRNET S.A. All rights reserved. // // Redistribution and use in source and binary forms, with or // without modification, are permitted provided that the following // conditions are met: // // 1. Redistributions of source code must retain the above // copyright notice, this list of conditions and the following // disclaimer. // // 2. Redistributions in binary form must reproduce the above // copyright notice, this list of conditions and the following // disclaimer in the documentation and/or other materials // provided with the distribution. // // THIS SOFTWARE IS PROVIDED BY GRNET S.A. ``AS IS'' AND ANY EXPRESS // OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED // WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GRNET S.A OR // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF // USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED // AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT // LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN // ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE // POSSIBILITY OF SUCH DAMAGE. // // The views and conclusions contained in the software and // documentation are those of the authors and should not be // interpreted as representing official policies, either expressed // or implied, of GRNET S.A. #import "PithosAccountNode.h" #import "PithosContainerNode.h" #import "ASIPithosAccountRequest.h" #import "ASIPithosContainer.h" #import "ASIDownloadCache.h" #import "PithosFileUtilities.h" @implementation PithosAccountNode #pragma mark - #pragma mark Object Lifecycle - (void)dealloc { [accountRequest clearDelegatesAndCancel]; [accountRequest release]; [containers release]; [super dealloc]; } #pragma mark - #pragma mark Properties - (NSString *)url { if (url == nil) url = [[ASIPithosRequest storageURL] copy]; return url; } - (NSArray *)children { @synchronized(self) { switch (freshness) { case PithosNodeStateFresh: break; case PithosNodeStateRefreshNeeded: freshness = PithosNodeStateRefreshing; accountRequest = [[ASIPithosAccountRequest listContainersRequestWithLimit:0 marker:nil shared:shared until:nil] retain]; accountRequest.delegate = self; accountRequest.didFinishSelector = @selector(accountRequestFinished:); accountRequest.didFailSelector = @selector(accountRequestFailed:); accountRequest.downloadCache = [ASIDownloadCache sharedCache]; [accountRequest startAsynchronous]; break; case PithosNodeStateRefreshing: break; case PithosNodeStateRefreshFinished: if (newChildren) { [children release]; children = newChildren; newChildren = nil; } freshness = PithosNodeStateFresh; default: break; } return children; } } - (NSString *)displayName { if (displayName == nil) { displayName = [[NSString alloc] initWithString:@"account"]; } return displayName; } #pragma mark - #pragma mark ASIHTTPRequestDelegate - (void)accountRequestFinished:(ASIPithosAccountRequest *)request { NSLog(@"URL: %@", [accountRequest url]); NSLog(@"cached: %d", [accountRequest didUseCachedResponse]); NSArray *someContainers = [accountRequest containers]; if (containers == nil) { containers = [[NSMutableArray alloc] initWithArray:someContainers]; } else { [containers addObjectsFromArray:someContainers]; } if ([someContainers count] < 10000) { if (!accountRequest.didUseCachedResponse || ([containers count] != [someContainers count]) || !children) { // Save new children NSLog(@"using newChildren"); newChildren = [[NSMutableArray alloc] init]; for (ASIPithosContainer *container in containers) { PithosContainerNode *node = [[[PithosContainerNode alloc] initWithPithosContainer:container] autorelease]; if (children) { NSUInteger oldIndex = [children indexOfObject:node]; if (oldIndex != NSNotFound) { // Use the same pointer value, if possible node = [children objectAtIndex:oldIndex]; node.pithosContainer = container; } } node.parent = self; node.shared = shared; [newChildren addObject:node]; } } // Else cache was used and all results were fetched during this request, so existing children can be reused [accountRequest release]; accountRequest = nil; [containers release]; containers = nil; @synchronized(self) { freshness = PithosNodeStateRefreshFinished; } // Notify observers that children are updated [[NSNotificationCenter defaultCenter] postNotificationName:@"PithosAccountNodeChildrenUpdated" object:self]; } else { [accountRequest release]; // Do an additional request to fetch more objects accountRequest = [[ASIPithosAccountRequest listContainersRequestWithLimit:0 marker:[[someContainers lastObject] name] shared:shared until:nil] retain]; accountRequest.delegate = self; accountRequest.downloadCache = [ASIDownloadCache sharedCache]; [accountRequest startAsynchronous]; } } - (void)accountRequestFailed:(ASIPithosAccountRequest *)request { [PithosFileUtilities httpRequestErrorAlertWithRequest:request]; [newChildren release]; newChildren = nil; [accountRequest release]; accountRequest = nil; [containers release]; containers = nil; @synchronized(self) { freshness = PithosNodeStateRefreshNeeded; } } @end