Initial implementation of 'my shared'.
[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 #import "PithosFileUtilities.h"
44
45 @implementation PithosAccountNode
46
47 #pragma mark -
48 #pragma mark Object Lifecycle
49
50 - (void)dealloc {
51     [accountRequest clearDelegatesAndCancel];
52     [accountRequest release];
53     [containers release];
54     [super dealloc];
55 }
56
57 #pragma mark -
58 #pragma mark Properties
59
60 - (NSString *)url {
61     if (url == nil) 
62         url = [[ASIPithosRequest storageURL] copy];
63     return url;
64 }
65
66 - (NSArray *)children {
67     @synchronized(self) {
68         switch (freshness) {
69             case PithosNodeStateFresh:
70                 break;
71             case PithosNodeStateRefreshNeeded:
72                 freshness = PithosNodeStateRefreshing;
73                 accountRequest = [[ASIPithosAccountRequest listContainersRequestWithLimit:0 
74                                                                                    marker:nil 
75                                                                                    shared:shared 
76                                                                                     until:nil] retain];
77                 accountRequest.delegate = self;
78                 accountRequest.didFinishSelector = @selector(accountRequestFinished:);
79                 accountRequest.didFailSelector = @selector(accountRequestFailed:);
80                 accountRequest.downloadCache = [ASIDownloadCache sharedCache];
81                 [accountRequest startAsynchronous];
82                 break;
83             case PithosNodeStateRefreshing:
84                 break;
85             case PithosNodeStateRefreshFinished:
86                 if (newChildren) {
87                     [children release];
88                     children = newChildren;
89                     newChildren = nil;
90                 }
91                 freshness = PithosNodeStateFresh;
92             default:
93                 break;
94         }
95         return children;
96     }
97 }
98
99 - (NSString *)displayName {
100     if (displayName == nil) {
101         displayName = [[NSString alloc] initWithString:@"account"];
102     }
103     return displayName;
104 }
105
106 #pragma mark -
107 #pragma mark ASIHTTPRequestDelegate
108
109 - (void)accountRequestFinished:(ASIPithosAccountRequest *)request {
110     NSLog(@"URL: %@", [accountRequest url]);
111     NSLog(@"cached: %d", [accountRequest didUseCachedResponse]);
112     
113     NSArray *someContainers = [accountRequest containers];
114     if (containers == nil) {
115         containers = [[NSMutableArray alloc] initWithArray:someContainers];
116     } else {
117         [containers addObjectsFromArray:someContainers];
118     }
119     if ([someContainers count] < 10000) {
120         if (!accountRequest.didUseCachedResponse || ([containers count] != [someContainers count]) || !children) {
121             // Save new children
122             NSLog(@"using newChildren");
123             newChildren = [[NSMutableArray alloc] init];
124             for (ASIPithosContainer *container in containers) {
125                 PithosContainerNode *node = [[[PithosContainerNode alloc] initWithPithosContainer:container] autorelease];
126                 if (children) {
127                     NSUInteger oldIndex = [children indexOfObject:node];
128                     if (oldIndex != NSNotFound) {
129                         // Use the same pointer value, if possible
130                         node = [children objectAtIndex:oldIndex];
131                         node.pithosContainer = container;
132                     }
133                 }
134                 node.parent = self;
135                 node.shared = shared;
136                 [newChildren addObject:node];
137             }
138         }
139         // Else cache was used and all results were fetched during this request, so existing children can be reused
140         [accountRequest release];
141         accountRequest = nil;
142         [containers release];
143         containers = nil;
144         @synchronized(self) {
145             freshness = PithosNodeStateRefreshFinished;
146         }
147         // Notify observers that children are updated
148         [[NSNotificationCenter defaultCenter] postNotificationName:@"PithosAccountNodeChildrenUpdated" object:self];
149     } else {
150         [accountRequest release];
151         // Do an additional request to fetch more objects
152         accountRequest = [[ASIPithosAccountRequest listContainersRequestWithLimit:0 
153                                                                            marker:[[someContainers lastObject] name] 
154                                                                            shared:shared 
155                                                                             until:nil] retain];
156         accountRequest.delegate = self;
157         accountRequest.downloadCache = [ASIDownloadCache sharedCache];
158         [accountRequest startAsynchronous];
159     }
160 }
161
162 - (void)accountRequestFailed:(ASIPithosAccountRequest *)request {
163     [PithosFileUtilities httpRequestErrorAlertWithRequest:request];
164     [newChildren release];
165     newChildren = nil;
166     [accountRequest release];
167     accountRequest = nil;
168     [containers release];
169     containers = nil;
170     @synchronized(self) {
171         freshness = PithosNodeStateRefreshNeeded;
172     }
173 }
174
175 @end