Loading all account containers.
[pithos-macos] / pithos-macos / PithosAccountNode.m
1 //
2 //  PithosNode.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)requestFinished:(ASIHTTPRequest *)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                 if (children) {
77                     NSUInteger oldIndex = [children indexOfObject:node];
78                     if (oldIndex != NSNotFound) {
79                         // Use the same pointer value, if possible
80                         node = [children objectAtIndex:oldIndex];
81                         node.pithosContainer = container;
82                     }
83                 }
84                 [newChildren addObject:node];
85             }
86         }
87         // Else cache was used and all results were fetched during this request, so existing children can be reused
88         [accountRequest release];
89         accountRequest = nil;
90         [containers release];
91         containers = nil;
92         // XXX sort children based on preferences
93         @synchronized(self) {
94             freshness = PithosNodeStateRefreshFinished;
95         }
96         // Notify observers that children are updated
97         [[NSNotificationCenter defaultCenter] postNotificationName:@"PithosAccountNodeChildrenUpdated" object:self];
98     } else {
99         [accountRequest release];
100         // Do an additional request to fetch more objects
101         accountRequest = [[ASIPithosAccountRequest listContainersRequestWithLimit:0 
102                                                                            marker:[[someContainers lastObject] name] 
103                                                                            shared:NO 
104                                                                             until:nil] retain];
105         accountRequest.delegate = self;
106         accountRequest.downloadCache = [ASIDownloadCache sharedCache];
107         [accountRequest startAsynchronous];
108     }
109 }
110
111 - (void)requestFailed:(ASIHTTPRequest *)request {
112     // XXX do something on error, cleanup
113     NSLog(@"error:%@", [accountRequest error]);
114     [newChildren release];
115     newChildren = nil;
116     [accountRequest release];
117     accountRequest = nil;
118     [containers release];
119     containers = nil;
120     @synchronized(self) {
121         freshness = PithosNodeStateRefreshNeeded;
122     }
123 }
124
125 #pragma mark -
126 #pragma mark Properties
127
128 - (NSString *)url {
129     if (url == nil) 
130         url = [[ASIPithosRequest storageURL] copy];
131     return url;
132 }
133
134 - (NSArray *)children {
135     @synchronized(self) {
136         switch (freshness) {
137             case PithosNodeStateFresh:
138                 break;
139             case PithosNodeStateRefreshNeeded:
140                 freshness = PithosNodeStateRefreshing;
141                 accountRequest = [[ASIPithosAccountRequest listContainersRequestWithLimit:0 
142                                                                                    marker:nil 
143                                                                                    shared:NO 
144                                                                                     until:nil] retain];
145                 accountRequest.delegate = self;
146                 accountRequest.downloadCache = [ASIDownloadCache sharedCache];
147                 [accountRequest startAsynchronous];
148                 break;
149             case PithosNodeStateRefreshing:
150                 break;
151             case PithosNodeStateRefreshFinished:
152                 if (newChildren) {
153                     [children release];
154                     children = newChildren;
155                     newChildren = nil;
156                 }
157                 freshness = PithosNodeStateFresh;
158             default:
159                 break;
160         }
161         return children;
162     }
163 }
164
165 - (NSString *)displayName {
166     if (displayName == nil) {
167         displayName = [[NSString alloc] initWithString:@"account"];
168     }
169     return displayName;
170 }
171
172 - (NSImage *)icon {
173     return nil;
174 }
175     
176 @end