#import "PithosObjectNode.h"
#import "PithosSubdirNode.h"
#import "ASIPithosContainerRequest.h"
+#import "ASIPithosContainer.h"
#import "ASIPithosObject.h"
#import "ASIDownloadCache.h"
static NSImage *sharedIcon = nil;
@implementation PithosContainerNode
+@synthesize pithosContainer;
+ (void)initialize {
if (self == [PithosContainerNode class])
- (id)initWithPithosContainer:(ASIPithosContainer *)aPithosContainer icon:(NSImage *)anIcon {
if ((self = [super init])) {
pithosContainer = [aPithosContainer retain];
- refreshing = NO;
prefix = nil;
icon = [anIcon retain];
childrenUpdatedNotificationName = @"PithosContainerNodeChildrenUpdated";
}
- (void)dealloc {
+ [containerRequest clearDelegatesAndCancel];
+ [containerRequest release];
[childrenUpdatedNotificationName release];
[prefix release];
[objects release];
#pragma mark -
#pragma mark ASIHTTPRequestDelegate
-- (void)requestFinished:(ASIPithosContainerRequest *)containerRequest {
+- (void)requestFinished:(ASIHTTPRequest *)request {
NSLog(@"URL: %@", [containerRequest url]);
NSLog(@"cached: %d", [containerRequest didUseCachedResponse]);
if (!containerRequest.didUseCachedResponse || ([objects count] != [someObjects count]) || !children) {
// Save new children
NSLog(@"using newChildren");
- NSMutableArray *newChildren = [NSMutableArray array];
+ newChildren = [[NSMutableArray alloc] init];
for (ASIPithosObject *object in objects) {
if (object.subdir) {
PithosSubdirNode *node = [[[PithosSubdirNode alloc] initWithPithosContainer:pithosContainer pithosObject:object] autorelease];
if (children) {
NSUInteger oldIndex = [children indexOfObject:node];
- if (oldIndex != NSNotFound)
+ if (oldIndex != NSNotFound) {
// Use the same pointer value, if possible
node = [children objectAtIndex:oldIndex];
+ node.pithosContainer = pithosContainer;
+ node.pithosObject = object;
+ }
}
- [newChildren addObject:node];
- } else {
+ [newChildren addObject:node];
+ } else if (([self class] != [PithosSubdirNode class]) || (![((PithosSubdirNode *)self).pithosObject.name isEqualToString:object.name])) {
+ // XXX the if above removes false objects due to trailing slash
+ // XXX this will change in the server, but it is fixed in the client for now
PithosObjectNode *node = [[[PithosObjectNode alloc] initWithPithosContainer:pithosContainer pithosObject:object] autorelease];
if (children) {
NSUInteger oldIndex = [children indexOfObject:node];
- if (oldIndex != NSNotFound)
+ if (oldIndex != NSNotFound) {
// Use the same pointer value, if possible
node = [children objectAtIndex:oldIndex];
+ node.pithosContainer = pithosContainer;
+ node.pithosObject = object;
+ }
}
[newChildren addObject:node];
}
}
- [children release];
- children = [newChildren retain];
}
- // Else cache was used and all results were fetched during this request, so previousChildren can be reused
+ // Else cache was used and all results were fetched during this request, so existing children can be reused
+ [containerRequest release];
+ containerRequest = nil;
[objects release];
objects = nil;
- // XXX sort then based on preferences
- refreshing = NO;
+ // XXX sort children based on preferences
+ @synchronized(self) {
+ freshness = PithosNodeStateRefreshFinished;
+ }
// Notify observers that children are updated
[[NSNotificationCenter defaultCenter] postNotificationName:childrenUpdatedNotificationName object:self];
} else {
+ [containerRequest release];
// Do an additional request to fetch more objects
- ASIPithosContainerRequest *newContainerRequest = [ASIPithosContainerRequest listObjectsRequestWithContainerName:pithosContainer.name
- limit:0
- marker:[[someObjects lastObject] name]
- prefix:prefix
- delimiter:@"/"
- path:nil
- meta:nil
- shared:NO
- until:nil];
- newContainerRequest.delegate = self;
- newContainerRequest.downloadCache = [ASIDownloadCache sharedCache];
- [newContainerRequest startAsynchronous];
+ containerRequest = [[ASIPithosContainerRequest listObjectsRequestWithContainerName:pithosContainer.name
+ limit:0
+ marker:[[someObjects lastObject] name]
+ prefix:prefix
+ delimiter:@"/"
+ path:nil
+ meta:nil
+ shared:NO
+ until:nil] retain];
+ containerRequest.delegate = self;
+ containerRequest.downloadCache = [ASIDownloadCache sharedCache];
+ [containerRequest startAsynchronous];
}
}
-- (void)requestFailed:(ASIPithosContainerRequest *)containerRequest {
+- (void)requestFailed:(ASIHTTPRequest *)request {
// XXX do something on error, cleanup
NSLog(@"error:%@", [containerRequest error]);
+ [newChildren release];
+ newChildren = nil;
+ [containerRequest release];
+ containerRequest = nil;
[objects release];
objects = nil;
- childrenDirty = YES;
- refreshing = NO;
+ @synchronized(self) {
+ freshness = PithosNodeStateRefreshNeeded;
+ }
}
#pragma mark -
}
- (NSArray *)children {
- if (childrenDirty) {
- @synchronized (self) {
- if (!refreshing) {
- refreshing = YES;
- childrenDirty = NO;
- ASIPithosContainerRequest *containerRequest = [ASIPithosContainerRequest listObjectsRequestWithContainerName:pithosContainer.name
- limit:0
- marker:nil
- prefix:prefix
- delimiter:@"/"
- path:nil
- meta:nil
- shared:NO
- until:nil];
+ @synchronized(self) {
+ switch (freshness) {
+ case PithosNodeStateFresh:
+ break;
+ case PithosNodeStateRefreshNeeded:
+ freshness = PithosNodeStateRefreshing;
+ containerRequest = [[ASIPithosContainerRequest listObjectsRequestWithContainerName:pithosContainer.name
+ limit:0
+ marker:nil
+ prefix:prefix
+ delimiter:@"/"
+ path:nil
+ meta:nil
+ shared:NO
+ until:nil] retain];
containerRequest.delegate = self;
containerRequest.downloadCache = [ASIDownloadCache sharedCache];
[containerRequest startAsynchronous];
- }
+ break;
+ case PithosNodeStateRefreshing:
+ break;
+ case PithosNodeStateRefreshFinished:
+ if (newChildren) {
+ [children release];
+ children = newChildren;
+ newChildren = nil;
+ }
+ freshness = PithosNodeStateFresh;
+ default:
+ break;
}
+ return children;
}
- return children;
}
- (NSString *)displayName {