All requests made asynchronous.
[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     NSLog(@"URL: %@", [request url]);
125     NSLog(@"cached: %d", [request didUseCachedResponse]);
126     
127     if ([request isEqualTo:applyMetadataObjectRequest]) {
128         int responseStatusCode = applyMetadataObjectRequest.responseStatusCode;
129         if (responseStatusCode != 202)
130             [PithosUtilities unexpectedResponseStatusAlertWithRequest:applyMetadataObjectRequest];
131         @synchronized(self) {
132             [applyMetadataObjectRequest release];
133             applyMetadataObjectRequest = nil;
134         }
135         if (responseStatusCode == 202)
136             [self refreshInfo];
137     } else if ([request isEqualTo:refreshMetadataObjectRequest]) {
138         [[pithosNodeInfoController window] makeFirstResponder:nil];
139         self.pithosObject = [refreshMetadataObjectRequest object];
140         @synchronized(self) {
141             [refreshMetadataObjectRequest release];
142             refreshMetadataObjectRequest = nil;
143         }
144     }
145 }
146
147 - (void)objectRequestFailed:(ASIPithosObjectRequest *)request {
148     if ([request isEqualTo:applyMetadataObjectRequest]) {
149         [PithosUtilities httpRequestErrorAlertWithRequest:applyMetadataObjectRequest];
150         @synchronized(self) {
151             [applyMetadataObjectRequest release];
152             applyMetadataObjectRequest = nil;
153         }
154     } else if ([request isEqualTo:refreshMetadataObjectRequest]) {
155         [PithosUtilities httpRequestErrorAlertWithRequest:refreshMetadataObjectRequest];
156         @synchronized(self) {
157             [refreshMetadataObjectRequest release];
158             refreshMetadataObjectRequest = nil;
159         }
160     }
161 }
162
163 #pragma mark -
164 #pragma mark Info
165
166 - (void)applyInfo {
167     @synchronized(self) {
168         if (applyMetadataObjectRequest == nil) {
169             [[pithosNodeInfoController window] makeFirstResponder:nil];
170             if (sharingAccount) {
171                 applyMetadataObjectRequest = [[ASIPithosObjectRequest updateObjectMetadataRequestWithContainerName:pithosContainer.name 
172                                                                                                         objectName:pithosObject.name 
173                                                                                                    contentEncoding:nil 
174                                                                                                 contentDisposition:nil 
175                                                                                                           manifest:nil 
176                                                                                                            sharing:nil
177                                                                                                           isPublic:(isPublic ? ASIPithosObjectRequestPublicTrue : ASIPithosObjectRequestPublicFalse) 
178                                                                                                           metadata:pithosObject.metadata
179                                                                                                             update:NO] retain];
180                 [applyMetadataObjectRequest setRequestUserFromDefaultTo:sharingAccount];
181             } else {
182                 applyMetadataObjectRequest = [[ASIPithosObjectRequest updateObjectMetadataRequestWithContainerName:pithosContainer.name 
183                                                                                                         objectName:pithosObject.name 
184                                                                                                    contentEncoding:pithosObject.contentEncoding 
185                                                                                                 contentDisposition:pithosObject.contentDisposition 
186                                                                                                           manifest:pithosObject.manifest 
187                                                                                                            sharing:(pithosObject.sharing ? pithosObject.sharing : @"")
188                                                                                                           isPublic:(isPublic ? ASIPithosObjectRequestPublicTrue : ASIPithosObjectRequestPublicFalse) 
189                                                                                                           metadata:pithosObject.metadata
190                                                                                                             update:NO] retain];
191             }
192             applyMetadataObjectRequest.delegate = self;
193             applyMetadataObjectRequest.didFinishSelector = @selector(objectRequestFinished:);
194             applyMetadataObjectRequest.didFailSelector = @selector(objectRequestFailed:);
195             [[PithosUtilities prepareRequest:applyMetadataObjectRequest priority:NSOperationQueuePriorityHigh] startAsynchronous];
196         }
197     }
198 }
199
200 - (void)refreshInfo {
201     @synchronized(self) {
202         if (refreshMetadataObjectRequest == nil) {
203             refreshMetadataObjectRequest = [[ASIPithosObjectRequest objectMetadataRequestWithContainerName:pithosContainer.name 
204                                                                                                 objectName:pithosObject.name] retain];
205             if (sharingAccount)
206                 [refreshMetadataObjectRequest setRequestUserFromDefaultTo:sharingAccount];
207             refreshMetadataObjectRequest.delegate = self;
208             refreshMetadataObjectRequest.didFinishSelector = @selector(objectRequestFinished:);
209             refreshMetadataObjectRequest.didFailSelector = @selector(objectRequestFailed:);
210             refreshMetadataObjectRequest.downloadCache = [ASIDownloadCache sharedCache];
211             [[PithosUtilities prepareRequest:refreshMetadataObjectRequest priority:NSOperationQueuePriorityHigh] startAsynchronous];
212         }
213     }
214 }
215
216 #pragma mark -
217 #pragma mark Actions
218
219 - (void)showPithosNodeInfo:(id)sender {
220     if (!pithosNodeInfoController)
221         pithosNodeInfoController = [[PithosObjectNodeInfoController alloc] initWithPithosNode:self];
222     [pithosNodeInfoController showWindow:sender];
223     [[pithosNodeInfoController window] makeKeyAndOrderFront:sender];
224     [NSApp activateIgnoringOtherApps:YES];
225 }
226
227 @end