Modify PithosNodes to use the global concurrent dispatch queue for ASIPithosRequest...
[pithos-macos] / pithos-macos / PithosObjectNode.m
1 //
2 //  PithosObjectNode.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 "PithosObjectNode.h"
39 #import "ASIPithosRequest.h"
40 #import "ASIPithosObjectRequest.h"
41 #import "ASIPithosContainer.h"
42 #import "ASIPithosObject.h"
43 #import "ASIDownloadCache.h"
44 #import "PithosUtilities.h"
45 #import "PithosObjectNodeInfoController.h"
46
47 @implementation PithosObjectNode
48 @synthesize pithosContainer, pithosObject;
49 @synthesize isPublic;
50
51 #pragma mark -
52 #pragma mark Object Lifecycle
53
54 - (id)initWithPithosContainer:(ASIPithosContainer *)aPithosContainer pithosObject:(ASIPithosObject *)aPithosObject {
55     if ((self = [super init])) {
56         self.pithosContainer = aPithosContainer;
57         self.pithosObject = aPithosObject;
58         isLeafItem = YES;
59     }
60     return self;
61 }
62
63 - (void)dealloc {
64     [refreshMetadataObjectRequest clearDelegatesAndCancel];
65     [refreshMetadataObjectRequest release];
66     [applyMetadataObjectRequest clearDelegatesAndCancel];
67     [applyMetadataObjectRequest release];
68     [pithosObject release];
69     [pithosContainer release];
70     [super dealloc];
71 }
72
73 #pragma mark -
74 #pragma mark Properties
75
76 - (NSString *)url {
77     if (url == nil)
78         url = [[NSString alloc] initWithFormat:@"object %@/%@/%@%@", 
79                (sharingAccount ? [ASIPithosRequest storageURLWithAuthUser:sharingAccount] : [ASIPithosRequest storageURL]), 
80                pithosContainer.name, 
81                pithosObject.name, 
82                (shared ? @"?shared" : @"")];
83     return url;
84 }
85
86 - (NSArray *)children {
87     return nil;
88 }
89
90 - (NSString *)displayName {
91     if (displayName == nil) {
92         displayName = [pithosObject.name lastPathComponent];
93         if([pithosObject.name hasSuffix:@"/"])
94             displayName = [displayName stringByAppendingString:@"/"];
95         [displayName retain];
96     }
97     return [[displayName copy] autorelease];
98 }
99
100 - (void)setDisplayName:(NSString *)aDisplayName {    
101 }
102
103 - (NSImage *)icon {
104     if (icon == nil)
105         icon = [[[NSWorkspace sharedWorkspace] iconForFileType:[pithosObject.name pathExtension]] retain];
106     return icon;
107 }
108
109 - (void)setPithosObject:(ASIPithosObject *)aPithosObject {
110     if (![pithosObject isEqualTo:aPithosObject]) {
111         [pithosObject release];
112         pithosObject = [aPithosObject retain];
113     }
114     self.isPublic = (pithosObject.publicURI != nil);
115     // Refresh browser if the object is in my shared and is no longer shared
116     if (shared && !pithosObject.sharing)
117         [[NSNotificationCenter defaultCenter] postNotificationName:@"PithosBrowserRefreshNeeeded" object:self];
118 }
119
120 #pragma mark -
121 #pragma mark ASIHTTPRequestDelegate
122
123 - (void)objectRequestFinished:(ASIPithosObjectRequest *)request {
124     NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
125     NSLog(@"URL: %@", [request url]);
126     NSLog(@"cached: %d", [request didUseCachedResponse]);
127     
128     if ([request isEqualTo:applyMetadataObjectRequest]) {
129         int responseStatusCode = applyMetadataObjectRequest.responseStatusCode;
130         if (responseStatusCode != 202)
131             [PithosUtilities unexpectedResponseStatusAlertWithRequest:applyMetadataObjectRequest];
132         @synchronized(self) {
133             [applyMetadataObjectRequest release];
134             applyMetadataObjectRequest = nil;
135         }
136         if (responseStatusCode == 202)
137             [self refreshInfo];
138     } else if ([request isEqualTo:refreshMetadataObjectRequest]) {
139         [[pithosNodeInfoController window] makeFirstResponder:nil];
140         self.pithosObject = [refreshMetadataObjectRequest object];
141         @synchronized(self) {
142             [refreshMetadataObjectRequest release];
143             refreshMetadataObjectRequest = nil;
144         }
145     }
146     [pool drain];
147 }
148
149 - (void)objectRequestFailed:(ASIPithosObjectRequest *)request {
150     NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
151     if ([request isEqualTo:applyMetadataObjectRequest]) {
152         [PithosUtilities httpRequestErrorAlertWithRequest:applyMetadataObjectRequest];
153         @synchronized(self) {
154             [applyMetadataObjectRequest release];
155             applyMetadataObjectRequest = nil;
156         }
157     } else if ([request isEqualTo:refreshMetadataObjectRequest]) {
158         [PithosUtilities httpRequestErrorAlertWithRequest:refreshMetadataObjectRequest];
159         @synchronized(self) {
160             [refreshMetadataObjectRequest release];
161             refreshMetadataObjectRequest = nil;
162         }
163     }
164     [pool drain];
165 }
166
167 #pragma mark -
168 #pragma mark Info
169
170 - (void)applyInfo {
171     @synchronized(self) {
172         if (applyMetadataObjectRequest == nil) {
173             [[pithosNodeInfoController window] makeFirstResponder:nil];
174             if (sharingAccount) {
175                 applyMetadataObjectRequest = [[ASIPithosObjectRequest updateObjectMetadataRequestWithContainerName:pithosContainer.name 
176                                                                                                         objectName:pithosObject.name 
177                                                                                                    contentEncoding:nil 
178                                                                                                 contentDisposition:nil 
179                                                                                                           manifest:nil 
180                                                                                                            sharing:nil
181                                                                                                           isPublic:(isPublic ? ASIPithosObjectRequestPublicTrue : ASIPithosObjectRequestPublicFalse) 
182                                                                                                           metadata:pithosObject.metadata
183                                                                                                             update:NO] retain];
184                 [applyMetadataObjectRequest setRequestUserFromDefaultTo:sharingAccount];
185             } else {
186                 applyMetadataObjectRequest = [[ASIPithosObjectRequest updateObjectMetadataRequestWithContainerName:pithosContainer.name 
187                                                                                                         objectName:pithosObject.name 
188                                                                                                    contentEncoding:pithosObject.contentEncoding 
189                                                                                                 contentDisposition:pithosObject.contentDisposition 
190                                                                                                           manifest:pithosObject.manifest 
191                                                                                                            sharing:(pithosObject.sharing ? pithosObject.sharing : @"")
192                                                                                                           isPublic:(isPublic ? ASIPithosObjectRequestPublicTrue : ASIPithosObjectRequestPublicFalse) 
193                                                                                                           metadata:pithosObject.metadata
194                                                                                                             update:NO] retain];
195             }
196             applyMetadataObjectRequest.delegate = self;
197             applyMetadataObjectRequest.didFinishSelector = @selector(performRequestFinishedDelegateInBackground:);
198             applyMetadataObjectRequest.didFailSelector = @selector(performRequestFailedDelegateInBackground:);
199             applyMetadataObjectRequest.userInfo = [NSMutableDictionary dictionaryWithObjectsAndKeys:
200                                                    [NSNumber numberWithInteger:NSOperationQueuePriorityHigh], @"priority", 
201                                                    [NSNumber numberWithUnsignedInteger:10], @"retries", 
202                                                    NSStringFromSelector(@selector(objectRequestFinished:)), @"didFinishSelector", 
203                                                    NSStringFromSelector(@selector(objectRequestFailed:)), @"didFailSelector", 
204                                                    nil];
205             [[PithosUtilities prepareRequest:applyMetadataObjectRequest priority:NSOperationQueuePriorityHigh] startAsynchronous];
206         }
207     }
208 }
209
210 - (void)refreshInfo {
211     @synchronized(self) {
212         if (refreshMetadataObjectRequest == nil) {
213             refreshMetadataObjectRequest = [[ASIPithosObjectRequest objectMetadataRequestWithContainerName:pithosContainer.name 
214                                                                                                 objectName:pithosObject.name] retain];
215             if (sharingAccount)
216                 [refreshMetadataObjectRequest setRequestUserFromDefaultTo:sharingAccount];
217             refreshMetadataObjectRequest.delegate = self;
218             refreshMetadataObjectRequest.didFinishSelector = @selector(performRequestFinishedDelegateInBackground:);
219             refreshMetadataObjectRequest.didFailSelector = @selector(performRequestFailedDelegateInBackground:);
220             refreshMetadataObjectRequest.userInfo = [NSMutableDictionary dictionaryWithObjectsAndKeys:
221                                                      [NSNumber numberWithInteger:NSOperationQueuePriorityHigh], @"priority", 
222                                                      [NSNumber numberWithUnsignedInteger:10], @"retries", 
223                                                      NSStringFromSelector(@selector(objectRequestFinished:)), @"didFinishSelector", 
224                                                      NSStringFromSelector(@selector(objectRequestFailed:)), @"didFailSelector", 
225                                                      nil];
226             refreshMetadataObjectRequest.downloadCache = [ASIDownloadCache sharedCache];
227             [[PithosUtilities prepareRequest:refreshMetadataObjectRequest priority:NSOperationQueuePriorityHigh] startAsynchronous];
228         }
229     }
230 }
231
232 #pragma mark -
233 #pragma mark Actions
234
235 - (void)showPithosNodeInfo:(id)sender {
236     if (!pithosNodeInfoController)
237         pithosNodeInfoController = [[PithosObjectNodeInfoController alloc] initWithPithosNode:self];
238     [pithosNodeInfoController showWindow:sender];
239     [[pithosNodeInfoController window] makeKeyAndOrderFront:sender];
240     [NSApp activateIgnoringOtherApps:YES];
241 }
242
243 @end