Revision 4a8699ab pithos-macos/PithosContainerNode.m

b/pithos-macos/PithosContainerNode.m
44 44
#import "ASIDownloadCache.h"
45 45
#import "PithosUtilities.h"
46 46
#import "PithosContainerNodeInfoController.h"
47
#import "PithosActivityFacility.h"
47 48

  
48 49
static NSImage *sharedIcon = nil;
49 50

  
......
132 133
                containerRequest.delegate = self;
133 134
                containerRequest.didFinishSelector = @selector(containerRequestFinished:);
134 135
                containerRequest.didFailSelector = @selector(containerRequestFailed:);
136
                containerRequest.userInfo = [NSMutableDictionary dictionaryWithObjectsAndKeys:
137
                                             [NSNumber numberWithUnsignedInteger:10], @"retries", 
138
                                             nil];
135 139
                if (!forcedRefresh)
136 140
                    containerRequest.downloadCache = [ASIDownloadCache sharedCache];
137 141
                [[PithosUtilities prepareRequest:containerRequest priority:NSOperationQueuePriorityVeryHigh] startAsynchronous];
......
188 192
#pragma mark -
189 193
#pragma mark ASIHTTPRequestDelegate
190 194

  
191
- (void)containerRequestFinished:(ASIPithosContainerRequest *)request {
192
    NSLog(@"URL: %@", [containerRequest url]);
193
    NSLog(@"cached: %d", [containerRequest didUseCachedResponse]);
194
    
195
    if ((pithosContainer.blockHash == nil) || (pithosContainer.blockSize == 0)) {
196
        pithosContainer.blockHash = [containerRequest blockHash];
197
        pithosContainer.blockSize = [containerRequest blockSize];
198
    }
199
    
200
    NSArray *someObjects = [containerRequest objects];
201
    if (objects == nil) {
202
        objects = [[NSMutableArray alloc] initWithArray:someObjects];
195
- (void)containerRequestFailed:(ASIPithosContainerRequest *)request {
196
    NSUInteger retries = [[containerRequest.userInfo objectForKey:@"retries"] unsignedIntegerValue];
197
    if (retries > 0) {
198
        ASIPithosContainerRequest *newContainerRequest = (ASIPithosContainerRequest *)[PithosUtilities copyRequest:containerRequest];
199
        [(NSMutableDictionary *)(newContainerRequest.userInfo)setObject:[NSNumber numberWithUnsignedInteger:(--retries)] forKey:@"retries"];
200
        [containerRequest release];
201
        containerRequest = newContainerRequest;
202
        [[PithosUtilities prepareRequest:containerRequest priority:NSOperationQueuePriorityVeryHigh] startAsynchronous];
203 203
    } else {
204
        [objects addObjectsFromArray:someObjects];
204
        NSString *message;
205
        NSError *error = [containerRequest error];
206
        if (error)
207
            message = [NSString stringWithFormat:@"Container listing failed: %@", error];
208
        else
209
            message = [NSString stringWithFormat:@"Container listing failed: (%d) %@", 
210
                       containerRequest.responseStatusCode, containerRequest.responseStatusMessage];
211
        [[PithosActivityFacility defaultPithosActivityFacility] startAndEndActivityWithType:PithosActivityOther message:message];
212
        [newChildren release];
213
        newChildren = nil;
214
        [containerRequest release];
215
        containerRequest = nil;
216
        [objects release];
217
        objects = nil;
218
        forcedRefresh = NO;
219
        @synchronized(self) {
220
            freshness = PithosNodeStateRefreshNeeded;
221
        }
205 222
    }
206
    if ([someObjects count] < 10000) {
207
        if (!containerRequest.didUseCachedResponse || ([objects count] != [someObjects count]) || !children) {
208
            // Save new children
209
            NSLog(@"using newChildren");
210
            newChildren = [[NSMutableArray alloc] init];
211
            NSArray *objectNames = [objects valueForKey:@"name"];
212
            NSMutableIndexSet *keptNodes = [NSMutableIndexSet indexSet];
213
            BOOL isSubdirNode = ([self class] == [PithosSubdirNode class]);
214
            for (ASIPithosObject *object in objects) {
215
                if (!isSubdirNode || 
216
                    [object.name hasPrefix:[((PithosSubdirNode *)self).prefix stringByAppendingString:@"/"]]) {
217
                    // The check above removes false objects due to trailing slash or same prefix
218
                    if (object.subdir) {
219
                        NSUInteger sameNameObjectIndex = [objectNames indexOfObject:[object.name substringToIndex:([object.name length] - 1)]];
220
                        if ((sameNameObjectIndex == NSNotFound) || 
221
                            ![PithosUtilities isContentTypeDirectory:[[objects objectAtIndex:sameNameObjectIndex] contentType]]) {
223
}
224

  
225
- (void)containerRequestFinished:(ASIPithosContainerRequest *)request {
226
    NSLog(@"List container finished: %@", [containerRequest url]);
227
    NSLog(@"Cached: %d", [containerRequest didUseCachedResponse]);
228
    if (containerRequest.responseStatusCode == 200) {
229
        if ((pithosContainer.blockHash == nil) || (pithosContainer.blockSize == 0)) {
230
            pithosContainer.blockHash = [containerRequest blockHash];
231
            pithosContainer.blockSize = [containerRequest blockSize];
232
        }
233
    
234
        NSArray *someObjects = [containerRequest objects];
235
        if (objects == nil) {
236
            objects = [[NSMutableArray alloc] initWithArray:someObjects];
237
        } else {
238
            [objects addObjectsFromArray:someObjects];
239
        }
240
        if ([someObjects count] < 10000) {
241
            if (!containerRequest.didUseCachedResponse || ([objects count] != [someObjects count]) || !children) {
242
                // Save new children
243
                NSLog(@"using newChildren");
244
                newChildren = [[NSMutableArray alloc] init];
245
                NSArray *objectNames = [objects valueForKey:@"name"];
246
                NSMutableIndexSet *keptNodes = [NSMutableIndexSet indexSet];
247
                BOOL isSubdirNode = ([self class] == [PithosSubdirNode class]);
248
                for (ASIPithosObject *object in objects) {
249
                    if (!isSubdirNode || 
250
                        [object.name hasPrefix:[((PithosSubdirNode *)self).prefix stringByAppendingString:@"/"]]) {
251
                        // The check above removes false objects due to trailing slash or same prefix
252
                        if (object.subdir) {
253
                            NSUInteger sameNameObjectIndex = [objectNames indexOfObject:[object.name substringToIndex:([object.name length] - 1)]];
254
                            if ((sameNameObjectIndex == NSNotFound) || 
255
                                ![PithosUtilities isContentTypeDirectory:[[objects objectAtIndex:sameNameObjectIndex] contentType]]) {
256
                                PithosSubdirNode *node = [[[PithosSubdirNode alloc] initWithPithosContainer:pithosContainer pithosObject:object] autorelease];
257
                                node.parent = self;
258
                                node.shared = shared;
259
                                node.sharingAccount = sharingAccount;
260
                                if (children) {
261
                                    NSUInteger oldIndex = [children indexOfObject:node];
262
                                    if (oldIndex != NSNotFound) {
263
                                        // Use the same pointer value, if possible
264
                                        node = [children objectAtIndex:oldIndex];
265
                                        node.pithosContainer = pithosContainer;
266
                                        node.pithosObject = object;
267
                                        [keptNodes addIndex:oldIndex];
268
                                    }
269
                                }
270
                                if (sharingAccount)
271
                                    node.pithosObject.allowedTo = [NSString stringWithString:@"read"];
272
                                [newChildren addObject:node];
273
                            }
274
                        } else if ([PithosUtilities isContentTypeDirectory:object.contentType]) {
222 275
                            PithosSubdirNode *node = [[[PithosSubdirNode alloc] initWithPithosContainer:pithosContainer pithosObject:object] autorelease];
223 276
                            node.parent = self;
224 277
                            node.shared = shared;
......
233 286
                                    [keptNodes addIndex:oldIndex];
234 287
                                }
235 288
                            }
236
                            if (sharingAccount)
237
                                node.pithosObject.allowedTo = [NSString stringWithString:@"read"];
238 289
                            [newChildren addObject:node];
239
                        }
240
                    } else if ([PithosUtilities isContentTypeDirectory:object.contentType]) {
241
                        PithosSubdirNode *node = [[[PithosSubdirNode alloc] initWithPithosContainer:pithosContainer pithosObject:object] autorelease];
242
                        node.parent = self;
243
                        node.shared = shared;
244
                        node.sharingAccount = sharingAccount;
245
                        if (children) {
246
                            NSUInteger oldIndex = [children indexOfObject:node];
247
                            if (oldIndex != NSNotFound) {
248
                                // Use the same pointer value, if possible
249
                                node = [children objectAtIndex:oldIndex];
250
                                node.pithosContainer = pithosContainer;
251
                                node.pithosObject = object;
252
                                [keptNodes addIndex:oldIndex];
253
                            }
254
                        }
255
                        [newChildren addObject:node];
256
                    } else {
257
                        PithosObjectNode *node = [[[PithosObjectNode alloc] initWithPithosContainer:pithosContainer pithosObject:object] autorelease];
258
                        node.parent = self;
259
                        node.shared = shared;
260
                        node.sharingAccount = sharingAccount;
261
                        if (children) {
262
                            NSUInteger oldIndex = [children indexOfObject:node];
263
                            if (oldIndex != NSNotFound) {
264
                                // Use the same pointer value, if possible
265
                                node = [children objectAtIndex:oldIndex];
266
                                node.pithosContainer = pithosContainer;
267
                                node.pithosObject = object;
268
                                [keptNodes addIndex:oldIndex];
290
                        } else {
291
                            PithosObjectNode *node = [[[PithosObjectNode alloc] initWithPithosContainer:pithosContainer pithosObject:object] autorelease];
292
                            node.parent = self;
293
                            node.shared = shared;
294
                            node.sharingAccount = sharingAccount;
295
                            if (children) {
296
                                NSUInteger oldIndex = [children indexOfObject:node];
297
                                if (oldIndex != NSNotFound) {
298
                                    // Use the same pointer value, if possible
299
                                    node = [children objectAtIndex:oldIndex];
300
                                    node.pithosContainer = pithosContainer;
301
                                    node.pithosObject = object;
302
                                    [keptNodes addIndex:oldIndex];
303
                                }
269 304
                            }
305
                            [newChildren addObject:node];                                
270 306
                        }
271
                        [newChildren addObject:node];                                
272 307
                    }
273 308
                }
309
                [[children objectsAtIndexes:
310
                  [[NSIndexSet indexSetWithIndexesInRange:NSMakeRange(0, [children count])] indexesPassingTest:^(NSUInteger idx, BOOL *stop){
311
                    if ([keptNodes containsIndex:idx])
312
                        return NO;
313
                    return YES;
314
                }]] makeObjectsPerformSelector:@selector(pithosNodeWillBeRemoved)];
315
            }
316
            // Else cache was used and all results were fetched during this request, so existing children can be reused
317
            [containerRequest release];
318
            containerRequest = nil;
319
            [objects release];
320
            objects = nil;
321
            forcedRefresh = NO;
322
            @synchronized(self) {
323
                freshness = PithosNodeStateRefreshFinished;
274 324
            }
275
            [[children objectsAtIndexes:
276
              [[NSIndexSet indexSetWithIndexesInRange:NSMakeRange(0, [children count])] indexesPassingTest:^(NSUInteger idx, BOOL *stop){
277
                if ([keptNodes containsIndex:idx])
278
                    return NO;
279
                return YES;
280
            }]] makeObjectsPerformSelector:@selector(pithosNodeWillBeRemoved)];
325
            // Notify observers that children are updated
326
            [[NSNotificationCenter defaultCenter] postNotificationName:childrenUpdatedNotificationName object:self];
327
        } else {
328
            [containerRequest release];
329
            // Do an additional request to fetch more objects
330
            containerRequest = [[ASIPithosContainerRequest listObjectsRequestWithContainerName:pithosContainer.name 
331
                                                                                         limit:0 
332
                                                                                        marker:[[someObjects lastObject] name] 
333
                                                                                        prefix:prefix 
334
                                                                                     delimiter:@"/" 
335
                                                                                          path:nil 
336
                                                                                          meta:nil 
337
                                                                                        shared:shared 
338
                                                                                         until:nil] retain];
339
            if (sharingAccount)
340
                [containerRequest setRequestUserFromDefaultTo:sharingAccount];
341
            containerRequest.delegate = self;
342
            containerRequest.didFinishSelector = @selector(containerRequestFinished:);
343
            containerRequest.didFailSelector = @selector(containerRequestFailed:);
344
            containerRequest.userInfo = [NSMutableDictionary dictionaryWithObjectsAndKeys:
345
                                         [NSNumber numberWithUnsignedInteger:10], @"retries", 
346
                                         nil];
347
            if (!forcedRefresh)
348
            containerRequest.downloadCache = [ASIDownloadCache sharedCache];
349
            [[PithosUtilities prepareRequest:containerRequest priority:NSOperationQueuePriorityVeryHigh] startAsynchronous];
281 350
        }
282
        // Else cache was used and all results were fetched during this request, so existing children can be reused
351
    } else if (containerRequest.responseStatusCode == 304) {
352
        // Container is not modified, so existing children can be reused
283 353
        [containerRequest release];
284 354
        containerRequest = nil;
285 355
        [objects release];
......
291 361
        // Notify observers that children are updated
292 362
        [[NSNotificationCenter defaultCenter] postNotificationName:childrenUpdatedNotificationName object:self];
293 363
    } else {
294
        [containerRequest release];
295
        // Do an additional request to fetch more objects
296
        containerRequest = [[ASIPithosContainerRequest listObjectsRequestWithContainerName:pithosContainer.name 
297
                                                                                     limit:0 
298
                                                                                    marker:[[someObjects lastObject] name] 
299
                                                                                    prefix:prefix 
300
                                                                                 delimiter:@"/" 
301
                                                                                      path:nil 
302
                                                                                      meta:nil 
303
                                                                                    shared:shared 
304
                                                                                     until:nil] retain];
305
        if (sharingAccount)
306
            [containerRequest setRequestUserFromDefaultTo:sharingAccount];
307
        containerRequest.delegate = self;
308
        if (!forcedRefresh)
309
        containerRequest.downloadCache = [ASIDownloadCache sharedCache];
310
        [[PithosUtilities prepareRequest:containerRequest priority:NSOperationQueuePriorityVeryHigh] startAsynchronous];
311
    }
312
}
313

  
314
- (void)containerRequestFailed:(ASIPithosContainerRequest *)request {
315
    [PithosUtilities httpRequestErrorAlertWithRequest:request];
316
    [newChildren release];
317
    newChildren = nil;
318
    [containerRequest release];
319
    containerRequest = nil;
320
    [objects release];
321
    objects = nil;
322
    forcedRefresh = NO;
323
    @synchronized(self) {
324
        freshness = PithosNodeStateRefreshNeeded;
364
        [self containerRequestFailed:containerRequest];
325 365
    }
326 366
}
327 367

  

Also available in: Unified diff