Statistics
| Branch: | Tag: | Revision:

root / pithos-macos / PithosAccountNode.m @ af3b9f06

History | View | Annotate | Download (7.9 kB)

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
static NSImage *sharedIcon = nil;
46

    
47
@implementation PithosAccountNode
48

    
49
+ (void)initialize {
50
	if (self == [PithosAccountNode class])
51
        sharedIcon = [[[NSWorkspace sharedWorkspace] iconForFileType:NSFileTypeForHFSTypeCode(kUserIcon)] retain];
52
}
53

    
54
#pragma mark -
55
#pragma mark Object Lifecycle
56

    
57
- (void)dealloc {
58
    [accountRequest clearDelegatesAndCancel];
59
    [accountRequest release];
60
    [containers release];
61
    [super dealloc];
62
}
63

    
64
#pragma mark -
65
#pragma mark Properties
66

    
67
- (NSString *)url {
68
    if (url == nil)
69
        url = [[NSString alloc] initWithFormat:@"%@%@", 
70
               (sharingAccount ? [ASIPithosRequest storageURLWithAuthUser:sharingAccount] : [ASIPithosRequest storageURL]), 
71
               (shared ? @"?shared" : @"")];
72
    return url;
73
}
74

    
75
- (NSArray *)children {
76
    @synchronized(self) {
77
        switch (freshness) {
78
            case PithosNodeStateFresh:
79
                break;
80
            case PithosNodeStateRefreshNeeded:
81
                freshness = PithosNodeStateRefreshing;
82
                accountRequest = [[ASIPithosAccountRequest listContainersRequestWithLimit:0 
83
                                                                                   marker:nil 
84
                                                                                   shared:shared 
85
                                                                                    until:nil] retain];
86
                if (sharingAccount)
87
                    [accountRequest setRequestUserFromDefaultTo:sharingAccount];
88
                accountRequest.delegate = self;
89
                accountRequest.didFinishSelector = @selector(accountRequestFinished:);
90
                accountRequest.didFailSelector = @selector(accountRequestFailed:);
91
                accountRequest.downloadCache = [ASIDownloadCache sharedCache];
92
                [accountRequest startAsynchronous];
93
                break;
94
            case PithosNodeStateRefreshing:
95
                break;
96
            case PithosNodeStateRefreshFinished:
97
                if (newChildren) {
98
                    [children release];
99
                    children = newChildren;
100
                    newChildren = nil;
101
                }
102
                freshness = PithosNodeStateFresh;
103
            default:
104
                break;
105
        }
106
        return children;
107
    }
108
}
109

    
110
- (NSString *)displayName {
111
    if (displayName == nil)
112
        return [NSString stringWithString:(sharingAccount ? sharingAccount : @"account")];
113
    return [[displayName copy] autorelease];
114
}
115

    
116
- (NSImage *)icon {
117
    if (icon == nil)
118
        icon = [sharedIcon retain];
119
    return icon;
120
}
121

    
122
#pragma mark -
123
#pragma mark ASIHTTPRequestDelegate
124

    
125
- (void)accountRequestFinished:(ASIPithosAccountRequest *)request {
126
    NSLog(@"URL: %@", [accountRequest url]);
127
    NSLog(@"cached: %d", [accountRequest didUseCachedResponse]);
128
    
129
    NSArray *someContainers = [accountRequest containers];
130
    if (containers == nil) {
131
        containers = [[NSMutableArray alloc] initWithArray:someContainers];
132
    } else {
133
        [containers addObjectsFromArray:someContainers];
134
    }
135
    if ([someContainers count] < 10000) {
136
        if (!accountRequest.didUseCachedResponse || ([containers count] != [someContainers count]) || !children) {
137
            // Save new children
138
            NSLog(@"using newChildren");
139
            newChildren = [[NSMutableArray alloc] init];
140
            NSMutableIndexSet *keptNodes = [NSMutableIndexSet indexSet];
141
            for (ASIPithosContainer *container in containers) {
142
                PithosContainerNode *node = [[[PithosContainerNode alloc] initWithPithosContainer:container] autorelease];
143
                node.parent = self;
144
                node.shared = shared;
145
                node.sharingAccount = sharingAccount;
146
                if (children) {
147
                    NSUInteger oldIndex = [children indexOfObject:node];
148
                    if (oldIndex != NSNotFound) {
149
                        // Use the same pointer value, if possible
150
                        node = [children objectAtIndex:oldIndex];
151
                        node.pithosContainer = container;
152
                        [keptNodes addIndex:oldIndex];
153
                    }
154
                }
155
                [newChildren addObject:node];
156
            }
157
            [[children objectsAtIndexes:
158
              [[NSIndexSet indexSetWithIndexesInRange:NSMakeRange(0, [children count])] indexesPassingTest:^(NSUInteger idx, BOOL *stop){
159
                if ([keptNodes containsIndex:idx])
160
                    return NO;
161
                return YES;
162
            }]] makeObjectsPerformSelector:@selector(pithosNodeWillBeRemoved)];
163
        }
164
        // Else cache was used and all results were fetched during this request, so existing children can be reused
165
        [accountRequest release];
166
        accountRequest = nil;
167
        [containers release];
168
        containers = nil;
169
        @synchronized(self) {
170
            freshness = PithosNodeStateRefreshFinished;
171
        }
172
        // Notify observers that children are updated
173
        [[NSNotificationCenter defaultCenter] postNotificationName:@"PithosAccountNodeChildrenUpdated" object:self];
174
    } else {
175
        [accountRequest release];
176
        // Do an additional request to fetch more objects
177
        accountRequest = [[ASIPithosAccountRequest listContainersRequestWithLimit:0 
178
                                                                           marker:[[someContainers lastObject] name] 
179
                                                                           shared:shared 
180
                                                                            until:nil] retain];
181
        if (sharingAccount)
182
            [accountRequest setRequestUserFromDefaultTo:sharingAccount];
183
        accountRequest.delegate = self;
184
        accountRequest.downloadCache = [ASIDownloadCache sharedCache];
185
        [accountRequest startAsynchronous];
186
    }
187
}
188

    
189
- (void)accountRequestFailed:(ASIPithosAccountRequest *)request {
190
    [PithosFileUtilities httpRequestErrorAlertWithRequest:request];
191
    [newChildren release];
192
    newChildren = nil;
193
    [accountRequest release];
194
    accountRequest = nil;
195
    [containers release];
196
    containers = nil;
197
    @synchronized(self) {
198
        freshness = PithosNodeStateRefreshNeeded;
199
    }
200
}
201

    
202
@end