Initial implementation of browser context menu.
[pithos-macos] / pithos-macos / PithosAccountNode.m
1 //
2 //  PithosAccountNode.m
3 //  pithos-macos
4 //
5 // Copyright 2011 GRNET S.A. All rights reserved.
6 //
7 // Redistribution and use in source and binary forms, with or
8 // without modification, are permitted provided that the following
9 // conditions are met:
10 // 
11 //   1. Redistributions of source code must retain the above
12 //      copyright notice, this list of conditions and the following
13 //      disclaimer.
14 // 
15 //   2. Redistributions in binary form must reproduce the above
16 //      copyright notice, this list of conditions and the following
17 //      disclaimer in the documentation and/or other materials
18 //      provided with the distribution.
19 // 
20 // THIS SOFTWARE IS PROVIDED BY GRNET S.A. ``AS IS'' AND ANY EXPRESS
21 // OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
22 // WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
23 // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GRNET S.A OR
24 // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
25 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
26 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
27 // USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
28 // AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 // LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
30 // ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
31 // POSSIBILITY OF SUCH DAMAGE.
32 // 
33 // The views and conclusions contained in the software and
34 // documentation are those of the authors and should not be
35 // interpreted as representing official policies, either expressed
36 // or implied, of GRNET S.A.
37
38 #import "PithosAccountNode.h"
39 #import "PithosContainerNode.h"
40 #import "ASIPithosAccountRequest.h"
41 #import "ASIPithosContainer.h"
42 #import "ASIDownloadCache.h"
43
44 @implementation PithosAccountNode
45
46 #pragma mark -
47 #pragma mark Object Lifecycle
48
49 - (void)dealloc {
50     [accountRequest clearDelegatesAndCancel];
51     [accountRequest release];
52     [containers release];
53     [super dealloc];
54 }
55
56 #pragma mark -
57 #pragma mark ASIHTTPRequestDelegate
58
59 - (void)accountRequestFinished:(ASIPithosAccountRequest *)request {
60     NSLog(@"URL: %@", [accountRequest url]);
61     NSLog(@"cached: %d", [accountRequest didUseCachedResponse]);
62     
63     NSArray *someContainers = [accountRequest containers];
64     if (containers == nil) {
65         containers = [[NSMutableArray alloc] initWithArray:someContainers];
66     } else {
67         [containers addObjectsFromArray:someContainers];
68     }
69     if ([someContainers count] < 10000) {
70         if (!accountRequest.didUseCachedResponse || ([containers count] != [someContainers count]) || !children) {
71             // Save new children
72             NSLog(@"using newChildren");
73             newChildren = [[NSMutableArray alloc] init];
74             for (ASIPithosContainer *container in containers) {
75                 PithosContainerNode *node = [[[PithosContainerNode alloc] initWithPithosContainer:container] autorelease];
76                 node.parent = self;
77                 if (children) {
78                     NSUInteger oldIndex = [children indexOfObject:node];
79                     if (oldIndex != NSNotFound) {
80                         // Use the same pointer value, if possible
81                         node = [children objectAtIndex:oldIndex];
82                         node.pithosContainer = container;
83                     }
84                 }
85                 [newChildren addObject:node];
86             }
87         }
88         // Else cache was used and all results were fetched during this request, so existing children can be reused
89         [accountRequest release];
90         accountRequest = nil;
91         [containers release];
92         containers = nil;
93         // XXX sort children based on preferences
94         @synchronized(self) {
95             freshness = PithosNodeStateRefreshFinished;
96         }
97         // Notify observers that children are updated
98         [[NSNotificationCenter defaultCenter] postNotificationName:@"PithosAccountNodeChildrenUpdated" object:self];
99     } else {
100         [accountRequest release];
101         // Do an additional request to fetch more objects
102         accountRequest = [[ASIPithosAccountRequest listContainersRequestWithLimit:0 
103                                                                            marker:[[someContainers lastObject] name] 
104                                                                            shared:NO 
105                                                                             until:nil] retain];
106         accountRequest.delegate = self;
107         accountRequest.downloadCache = [ASIDownloadCache sharedCache];
108         [accountRequest startAsynchronous];
109     }
110 }
111
112 - (void)accountRequestFailed:(ASIPithosAccountRequest *)request {
113     // XXX do something on error, cleanup
114     NSLog(@"error:%@", [accountRequest error]);
115     [newChildren release];
116     newChildren = nil;
117     [accountRequest release];
118     accountRequest = nil;
119     [containers release];
120     containers = nil;
121     @synchronized(self) {
122         freshness = PithosNodeStateRefreshNeeded;
123     }
124 }
125
126 #pragma mark -
127 #pragma mark Properties
128
129 - (NSString *)url {
130     if (url == nil) 
131         url = [[ASIPithosRequest storageURL] copy];
132     return url;
133 }
134
135 - (NSArray *)children {
136     @synchronized(self) {
137         switch (freshness) {
138             case PithosNodeStateFresh:
139                 break;
140             case PithosNodeStateRefreshNeeded:
141                 freshness = PithosNodeStateRefreshing;
142                 accountRequest = [[ASIPithosAccountRequest listContainersRequestWithLimit:0 
143                                                                                    marker:nil 
144                                                                                    shared:NO 
145                                                                                     until:nil] retain];
146                 accountRequest.delegate = self;
147                 accountRequest.didFinishSelector = @selector(accountRequestFinished:);
148                 accountRequest.didFailSelector = @selector(accountRequestFailed:);
149                 accountRequest.downloadCache = [ASIDownloadCache sharedCache];
150                 [accountRequest startAsynchronous];
151                 break;
152             case PithosNodeStateRefreshing:
153                 break;
154             case PithosNodeStateRefreshFinished:
155                 if (newChildren) {
156                     [children release];
157                     children = newChildren;
158                     newChildren = nil;
159                 }
160                 freshness = PithosNodeStateFresh;
161             default:
162                 break;
163         }
164         return children;
165     }
166 }
167
168 - (NSString *)displayName {
169     if (displayName == nil) {
170         displayName = [[NSString alloc] initWithString:@"account"];
171     }
172     return displayName;
173 }
174
175 - (NSImage *)icon {
176     return nil;
177 }
178     
179 @end