summary |
shortlog |
log |
commit | commitdiff |
tree
raw |
patch |
inline | side by side (from parent 1:
63db4b9)
Other minor fixes and changes.
// or implied, of GRNET S.A.
#import "PithosNode.h"
// or implied, of GRNET S.A.
#import "PithosNode.h"
+@class ASIPithosAccountRequest;
@interface PithosAccountNode : PithosNode {
NSMutableArray *containers;
@interface PithosAccountNode : PithosNode {
NSMutableArray *containers;
+ ASIPithosAccountRequest *accountRequest;
+@end
\ No newline at end of file
#pragma mark -
#pragma mark Object Lifecycle
#pragma mark -
#pragma mark Object Lifecycle
-- (id)init {
- if ((self = [super init])) {
- refreshing = NO;
- }
- return self;
-}
-
+ [accountRequest clearDelegatesAndCancel];
+ [accountRequest release];
[containers release];
[super dealloc];
}
[containers release];
[super dealloc];
}
#pragma mark -
#pragma mark ASIHTTPRequestDelegate
#pragma mark -
#pragma mark ASIHTTPRequestDelegate
-- (void)requestFinished:(ASIPithosAccountRequest *)accountRequest {
+- (void)requestFinished:(ASIHTTPRequest *)request {
NSLog(@"URL: %@", [accountRequest url]);
NSLog(@"cached: %d", [accountRequest didUseCachedResponse]);
NSLog(@"URL: %@", [accountRequest url]);
NSLog(@"cached: %d", [accountRequest didUseCachedResponse]);
if (!accountRequest.didUseCachedResponse || ([containers count] != [someContainers count]) || !children) {
// Save new children
NSLog(@"using newChildren");
if (!accountRequest.didUseCachedResponse || ([containers count] != [someContainers count]) || !children) {
// Save new children
NSLog(@"using newChildren");
- NSMutableArray *newChildren = [NSMutableArray array];
+ newChildren = [NSMutableArray array];
for (ASIPithosContainer *container in containers) {
PithosContainerNode *node = [[[PithosContainerNode alloc] initWithPithosContainer:container] autorelease];
if (children) {
NSUInteger oldIndex = [children indexOfObject:node];
for (ASIPithosContainer *container in containers) {
PithosContainerNode *node = [[[PithosContainerNode alloc] initWithPithosContainer:container] 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];
// Use the same pointer value, if possible
node = [children objectAtIndex:oldIndex];
+ node.pithosContainer = container;
+ }
}
[newChildren addObject:node];
}
}
[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
+ [accountRequest release];
+ accountRequest = nil;
[containers release];
containers = nil;
// XXX sort children based on preferences
[containers release];
containers = nil;
// XXX sort children based on preferences
+ @synchronized(self) {
+ freshness = PithosNodeStateRefreshFinished;
+ }
// Notify observers that children are updated
[[NSNotificationCenter defaultCenter] postNotificationName:@"PithosAccountNodeChildrenUpdated" object:self];
} else {
// Notify observers that children are updated
[[NSNotificationCenter defaultCenter] postNotificationName:@"PithosAccountNodeChildrenUpdated" object:self];
} else {
+ [accountRequest release];
// Do an additional request to fetch more objects
// Do an additional request to fetch more objects
- ASIPithosAccountRequest *newAccountRequest = [ASIPithosAccountRequest listContainersRequestWithLimit:0
- marker:[[someContainers lastObject] name]
- shared:NO
- until:nil];
- newAccountRequest.delegate = self;
- newAccountRequest.downloadCache = [ASIDownloadCache sharedCache];
- [newAccountRequest startAsynchronous];
+ accountRequest = [[ASIPithosAccountRequest listContainersRequestWithLimit:0
+ marker:[[someContainers lastObject] name]
+ shared:NO
+ until:nil] retain];
+ accountRequest.delegate = self;
+ accountRequest.downloadCache = [ASIDownloadCache sharedCache];
+ [accountRequest startAsynchronous];
-- (void)requestFailed:(ASIPithosAccountRequest *)accountRequest {
+- (void)requestFailed:(ASIHTTPRequest *)request {
// XXX do something on error, cleanup
NSLog(@"error:%@", [accountRequest error]);
// XXX do something on error, cleanup
NSLog(@"error:%@", [accountRequest error]);
+ [newChildren release];
+ newChildren = nil;
+ [accountRequest release];
+ accountRequest = nil;
[containers release];
containers = nil;
[containers release];
containers = nil;
- childrenDirty = YES;
- refreshing = NO;
+ @synchronized(self) {
+ freshness = PithosNodeStateRefreshNeeded;
+ }
}
- (NSArray *)children {
}
- (NSArray *)children {
- if (childrenDirty) {
- @synchronized (self) {
- if (!refreshing) {
- refreshing = YES;
- childrenDirty = NO;
- ASIPithosAccountRequest *accountRequest = [ASIPithosAccountRequest listContainersRequestWithLimit:0
- marker:nil
- shared:NO
- until:nil];
+ @synchronized(self) {
+ switch (freshness) {
+ case PithosNodeStateFresh:
+ break;
+ case PithosNodeStateRefreshNeeded:
+ freshness = PithosNodeStateRefreshing;
+ accountRequest = [[ASIPithosAccountRequest listContainersRequestWithLimit:0
+ marker:nil
+ shared:NO
+ until:nil] retain];
accountRequest.delegate = self;
accountRequest.downloadCache = [ASIDownloadCache sharedCache];
[accountRequest startAsynchronous];
accountRequest.delegate = self;
accountRequest.downloadCache = [ASIDownloadCache sharedCache];
[accountRequest startAsynchronous];
+ break;
+ case PithosNodeStateRefreshing:
+ break;
+ case PithosNodeStateRefreshFinished:
+ if (newChildren) {
+ [children release];
+ children = newChildren;
+ newChildren = nil;
+ }
+ freshness = PithosNodeStateFresh;
+ default:
+ break;
}
- (NSString *)displayName {
}
- (NSString *)displayName {
#pragma Observers
- (void)pithosNodeChildrenUpdated:(NSNotification *)notification {
#pragma Observers
- (void)pithosNodeChildrenUpdated:(NSNotification *)notification {
- if ([[browser parentForItemsInColumn:[browser lastColumn]] isEqualTo:[notification object]])
- [browser reloadColumn:[browser lastColumn]];
+ PithosNode *node = (PithosNode *)[notification object];
+ NSInteger lastColumn = [browser lastColumn];
+ for (NSInteger column = lastColumn; column >= 0; column--) {
+ if ([[browser parentForItemsInColumn:column] isEqualTo:node]) {
+ [browser reloadColumn:column];
+ if ((column == lastColumn - 1) && ([[browser parentForItemsInColumn:lastColumn] isLeafItem])) {
+ // This reloads the preview column
+ [browser setLastColumn:column];
+ [browser addColumn];
+ }
+ return;
+ }
+ }
}
#pragma mark -
#pragma Actions
- (IBAction)refresh:(id)sender {
}
#pragma mark -
#pragma Actions
- (IBAction)refresh:(id)sender {
- [[browser parentForItemsInColumn:[browser lastColumn]] invalidateChildren];
- [browser reloadColumn:[browser lastColumn]];
+ for (NSInteger column = [browser lastColumn]; column >= 0; column--) {
+ [(PithosNode *)[browser parentForItemsInColumn:column] invalidateChildren];
+ }
+ [browser validateVisibleColumns];
// return suggestedWidth;
//}
// return suggestedWidth;
//}
+- (BOOL)browser:(NSBrowser *)sender isColumnValid:(NSInteger)column {
+ return NO;
+}
+
#pragma mark -
#pragma NSSplitViewDelegate
- (CGFloat)splitView:(NSSplitView *)splitView constrainMinCoordinate:(CGFloat)proposedMinimumPosition ofSubviewAt:(NSInteger)dividerIndex {
#pragma mark -
#pragma NSSplitViewDelegate
- (CGFloat)splitView:(NSSplitView *)splitView constrainMinCoordinate:(CGFloat)proposedMinimumPosition ofSubviewAt:(NSInteger)dividerIndex {
}
- (CGFloat)splitView:(NSSplitView *)splitView constrainMaxCoordinate:(CGFloat)proposedMaximumPosition ofSubviewAt:(NSInteger)dividerIndex {
}
- (CGFloat)splitView:(NSSplitView *)splitView constrainMaxCoordinate:(CGFloat)proposedMaximumPosition ofSubviewAt:(NSInteger)dividerIndex {
// or implied, of GRNET S.A.
#import "PithosNode.h"
// or implied, of GRNET S.A.
#import "PithosNode.h"
-#import "ASIPithosContainer.h"
+@class ASIPithosContainer;
+@class ASIPithosContainerRequest;
@interface PithosContainerNode : PithosNode {
ASIPithosContainer *pithosContainer;
NSMutableArray *objects;
@interface PithosContainerNode : PithosNode {
ASIPithosContainer *pithosContainer;
NSMutableArray *objects;
+ ASIPithosContainerRequest *containerRequest;
NSString *childrenUpdatedNotificationName;
}
NSString *childrenUpdatedNotificationName;
}
- (id)initWithContainerName:(NSString *)aContainerName;
- (id)initWithContainerName:(NSString *)aContainerName icon:(NSImage *)anIcon;
- (id)initWithContainerName:(NSString *)aContainerName;
- (id)initWithContainerName:(NSString *)aContainerName icon:(NSImage *)anIcon;
+@property(retain) ASIPithosContainer *pithosContainer;
+
+@end
\ No newline at end of file
#import "PithosObjectNode.h"
#import "PithosSubdirNode.h"
#import "ASIPithosContainerRequest.h"
#import "PithosObjectNode.h"
#import "PithosSubdirNode.h"
#import "ASIPithosContainerRequest.h"
+#import "ASIPithosContainer.h"
#import "ASIPithosObject.h"
#import "ASIDownloadCache.h"
static NSImage *sharedIcon = nil;
@implementation PithosContainerNode
#import "ASIPithosObject.h"
#import "ASIDownloadCache.h"
static NSImage *sharedIcon = nil;
@implementation PithosContainerNode
+@synthesize pithosContainer;
+ (void)initialize {
if (self == [PithosContainerNode class])
+ (void)initialize {
if (self == [PithosContainerNode class])
- (id)initWithPithosContainer:(ASIPithosContainer *)aPithosContainer icon:(NSImage *)anIcon {
if ((self = [super init])) {
pithosContainer = [aPithosContainer retain];
- (id)initWithPithosContainer:(ASIPithosContainer *)aPithosContainer icon:(NSImage *)anIcon {
if ((self = [super init])) {
pithosContainer = [aPithosContainer retain];
prefix = nil;
icon = [anIcon retain];
childrenUpdatedNotificationName = @"PithosContainerNodeChildrenUpdated";
prefix = nil;
icon = [anIcon retain];
childrenUpdatedNotificationName = @"PithosContainerNodeChildrenUpdated";
+ [containerRequest clearDelegatesAndCancel];
+ [containerRequest release];
[childrenUpdatedNotificationName release];
[prefix release];
[objects release];
[childrenUpdatedNotificationName release];
[prefix release];
[objects release];
#pragma mark -
#pragma mark ASIHTTPRequestDelegate
#pragma mark -
#pragma mark ASIHTTPRequestDelegate
-- (void)requestFinished:(ASIPithosContainerRequest *)containerRequest {
+- (void)requestFinished:(ASIHTTPRequest *)request {
NSLog(@"URL: %@", [containerRequest url]);
NSLog(@"cached: %d", [containerRequest didUseCachedResponse]);
NSLog(@"URL: %@", [containerRequest url]);
NSLog(@"cached: %d", [containerRequest didUseCachedResponse]);
if (!containerRequest.didUseCachedResponse || ([objects count] != [someObjects count]) || !children) {
// Save new children
NSLog(@"using newChildren");
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];
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];
// 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];
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];
// Use the same pointer value, if possible
node = [children objectAtIndex:oldIndex];
+ node.pithosContainer = pithosContainer;
+ node.pithosObject = object;
+ }
}
[newChildren addObject:node];
}
}
}
[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;
[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 {
// Notify observers that children are updated
[[NSNotificationCenter defaultCenter] postNotificationName:childrenUpdatedNotificationName object:self];
} else {
+ [containerRequest release];
// Do an additional request to fetch more objects
// 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]);
// XXX do something on error, cleanup
NSLog(@"error:%@", [containerRequest error]);
+ [newChildren release];
+ newChildren = nil;
+ [containerRequest release];
+ containerRequest = nil;
[objects release];
objects = nil;
[objects release];
objects = nil;
- childrenDirty = YES;
- refreshing = NO;
+ @synchronized(self) {
+ freshness = PithosNodeStateRefreshNeeded;
+ }
}
- (NSArray *)children {
}
- (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];
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;
}
- (NSString *)displayName {
}
- (NSString *)displayName {
// interpreted as representing official policies, either expressed
// or implied, of GRNET S.A.
// interpreted as representing official policies, either expressed
// or implied, of GRNET S.A.
+#define PithosNodeStateFresh 0
+#define PithosNodeStateRefreshNeeded 1
+#define PithosNodeStateRefreshing 2
+#define PithosNodeStateRefreshFinished 3
+
@interface PithosNode : NSObject {
@interface PithosNode : NSObject {
NSString *url;
NSMutableArray *children;
NSString *url;
NSMutableArray *children;
- BOOL childrenDirty;
- NSMutableArray *previousChildren;
+ NSMutableArray *newChildren;
NSString *displayName;
BOOL isLeafItem;
NSString *displayName;
BOOL isLeafItem;
@property(readonly) NSString *version;
- (void)invalidateChildren;
@property(readonly) NSString *version;
- (void)invalidateChildren;
+- (void)invalidateChildrenRecursive;
+@end
\ No newline at end of file
- (id)init {
if ((self == [super init])) {
- (id)init {
if ((self == [super init])) {
+ freshness = PithosNodeStateRefreshNeeded;
isLeafItem = NO;
}
return self;
isLeafItem = NO;
}
return self;
- (void)dealloc {
[icon release];
[displayName release];
- (void)dealloc {
[icon release];
[displayName release];
- [previousChildren release];
[children release];
[url release];
[super dealloc];
}
- (BOOL)isEqual:(id)anObject {
[children release];
[url release];
[super dealloc];
}
- (BOOL)isEqual:(id)anObject {
- if ([anObject isKindOfClass:[self class]]) {
- return [((PithosNode *)anObject).url isEqual:self.url];
- }
- return NO;
+ return ([anObject isKindOfClass:[self class]] && [((PithosNode *)anObject).url isEqual:self.url]);
}
- (void)invalidateChildren {
}
- (void)invalidateChildren {
- childrenDirty = YES;
- for (PithosNode *child in children) {
- [child invalidateChildren];
+ if (freshness == PithosNodeStateFresh)
+ freshness = PithosNodeStateRefreshNeeded;
+}
+
+- (void)invalidateChildrenRecursive {
+ if (freshness == PithosNodeStateFresh) {
+ for (PithosNode *child in children) {
+ [child invalidateChildrenRecursive];
+ }
+ freshness = PithosNodeStateRefreshNeeded;
// or implied, of GRNET S.A.
#import "PithosNode.h"
// or implied, of GRNET S.A.
#import "PithosNode.h"
-#import "ASIPithosContainer.h"
-#import "ASIPithosObject.h"
+@class ASIPithosContainer;
+@class ASIPithosObject;
@interface PithosObjectNode : PithosNode {
ASIPithosContainer *pithosContainer;
@interface PithosObjectNode : PithosNode {
ASIPithosContainer *pithosContainer;
- (id)initWithPithosContainer:(ASIPithosContainer *)aPithosContainer pithosObject:(ASIPithosObject *)aPithosObject;
- (id)initWithPithosContainer:(ASIPithosContainer *)aPithosContainer pithosObject:(ASIPithosObject *)aPithosObject;
+@property (retain) ASIPithosContainer *pithosContainer;
+@property (retain) ASIPithosObject *pithosObject;
+
+@end
\ No newline at end of file
#import "PithosObjectNode.h"
#import "ASIPithosRequest.h"
#import "PithosObjectNode.h"
#import "ASIPithosRequest.h"
+#import "ASIPithosContainer.h"
+#import "ASIPithosObject.h"
@implementation PithosObjectNode
@implementation PithosObjectNode
+@synthesize pithosContainer, pithosObject;
#pragma mark -
#pragma mark Object Lifecycle
#pragma mark -
#pragma mark Object Lifecycle
- (NSString *)displayName {
if (displayName == nil) {
- (NSString *)displayName {
if (displayName == nil) {
+ // XXX check if there are problems with . or other special characters
displayName = [pithosObject.name lastPathComponent];
if([pithosObject.name hasSuffix:@"/"])
displayName = [displayName stringByAppendingString:@"/"];
displayName = [pithosObject.name lastPathComponent];
if([pithosObject.name hasSuffix:@"/"])
displayName = [displayName stringByAppendingString:@"/"];
// or implied, of GRNET S.A.
#import "PithosContainerNode.h"
// or implied, of GRNET S.A.
#import "PithosContainerNode.h"
-#import "ASIPithosObject.h"
@interface PithosSubdirNode : PithosContainerNode {
ASIPithosObject *pithosObject;
@interface PithosSubdirNode : PithosContainerNode {
ASIPithosObject *pithosObject;
- (id)initWithPithosContainer:(ASIPithosContainer *)aPithosContainer pithosObject:(ASIPithosObject *)aPithosObject;
- (id)initWithPithosContainer:(ASIPithosContainer *)aPithosContainer pithosObject:(ASIPithosObject *)aPithosObject;
+@property (retain) ASIPithosObject *pithosObject;
+
+@end
\ No newline at end of file
#import "PithosSubdirNode.h"
#import "ASIPithosRequest.h"
#import "PithosSubdirNode.h"
#import "ASIPithosRequest.h"
+#import "ASIPithosContainer.h"
+#import "ASIPithosObject.h"
static NSImage *sharedIcon = nil;
@implementation PithosSubdirNode
static NSImage *sharedIcon = nil;
@implementation PithosSubdirNode
+@synthesize pithosObject;
+ (void)initialize {
if (self == [PithosSubdirNode class])
+ (void)initialize {
if (self == [PithosSubdirNode class])
if ((self = [super init])) {
pithosContainer = [aPithosContainer retain];
pithosObject = [aPithosObject retain];
if ((self = [super init])) {
pithosContainer = [aPithosContainer retain];
pithosObject = [aPithosObject retain];
prefix = [[pithosObject.name substringToIndex:([pithosObject.name length] - 1)] retain];
childrenUpdatedNotificationName = @"PithosSubdirNodeChildrenUpdated";
}
prefix = [[pithosObject.name substringToIndex:([pithosObject.name length] - 1)] retain];
childrenUpdatedNotificationName = @"PithosSubdirNodeChildrenUpdated";
}
}
- (NSString *)displayName {
}
- (NSString *)displayName {
+ // XXX check if there are problems with . or other special characters
return [pithosObject.name lastPathComponent];
}
return [pithosObject.name lastPathComponent];
}