Fix bugs
[pithos-macos] / pithos-macos / PithosNode.m
1 //
2 //  PithosNode.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 "PithosNode.h"
39 #import "PithosNodeInfoController.h"
40 #import "ASIPithosRequest.h"
41
42 @implementation PithosNode
43 @synthesize forcedRefresh, pithosAccountManager, parent, shared, sharingAccount, childrenUpdatedNotificationName,
44             inheritChildrenUpdatedNotificationName, displayName, isLeafItem, icon;
45 @dynamic url, children, pithos, pithosAccount, pithosContainer, pithosObject;
46
47 #pragma mark -
48 #pragma mark Object Lifecycle
49
50 - (id)init {
51     if ((self = [super init])) {
52         pithosAccountManager = nil;
53         freshness = PithosNodeStateRefreshNeeded;
54         forcedRefresh = NO;
55         shared = NO;
56         isLeafItem = NO;
57         self.childrenUpdatedNotificationName = @"PithosNodeChildrenUpdated";
58         inheritChildrenUpdatedNotificationName = NO;
59     }
60     return self;
61 }
62
63
64 - (BOOL)isEqual:(id)anObject {
65     return ([anObject isKindOfClass:[self class]] && [((PithosNode *)anObject).url isEqual:self.url]);
66 }
67
68 - (NSUInteger)hash {
69     return self.url.hash;
70 }
71
72 #pragma mark -
73 #pragma mark Properties
74
75 - (void)setShared:(BOOL)aShared {
76     if (shared != aShared) {
77         shared = aShared;
78         url = nil;
79     }
80 }
81
82 - (void)setSharingAccount:(NSString *)aSharingAccount {
83     if (![sharingAccount isEqualToString:aSharingAccount]) {
84         sharingAccount = aSharingAccount;
85         url = nil;
86     }
87 }
88
89 #pragma mark -
90 #pragma mark Actions
91
92 - (void)invalidateChildren {
93     if (freshness == PithosNodeStateFresh)
94         freshness = PithosNodeStateRefreshNeeded;
95 }
96
97 - (void)invalidateChildrenRecursive {    
98     if (freshness == PithosNodeStateFresh) {
99         for (PithosNode *child in children) {
100             [child invalidateChildrenRecursive];
101         }
102         freshness = PithosNodeStateRefreshNeeded;
103     }
104 }
105
106 - (void)refresh {
107     [self invalidateChildren];
108     self.children;
109 }
110
111 - (void)forceRefresh {
112     forcedRefresh = YES;
113     [self refresh];
114 }
115
116 - (void)postChildrenUpdatedNotificationName {
117     // Notify observers that children are updated
118     if (inheritChildrenUpdatedNotificationName) {
119         PithosNode *ancestor = self;
120         while (ancestor && ancestor.parent) {
121             ancestor = ancestor.parent;
122         }
123         if (ancestor && ancestor.childrenUpdatedNotificationName) {
124             [[NSNotificationCenter defaultCenter] postNotificationName:ancestor.childrenUpdatedNotificationName object:self];
125         }
126     } else if (childrenUpdatedNotificationName) {
127         [[NSNotificationCenter defaultCenter] postNotificationName:childrenUpdatedNotificationName object:self];
128     }
129 }
130
131 - (void)showPithosNodeInfo:(id)sender {
132     // Abstract method
133 }
134
135 - (void)pithosNodeInfoWillClose:(id)sender {
136     if (pithosNodeInfoController) {
137         pithosNodeInfoController = nil;
138     }
139 }
140
141 - (void)pithosNodeWillBeRemoved {
142     if (pithosNodeInfoController) {
143         pithosNodeInfoController.node = nil;
144         [[pithosNodeInfoController window] close];
145     }
146     for (PithosNode *child in children) {
147         [child pithosNodeWillBeRemoved];
148     }
149 }
150
151 #pragma mark -
152 #pragma mark ASIHTTPRequestDelegate
153
154 - (void)performRequestFinishedDelegateInBackground:(ASIPithosRequest *)request {
155     dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^{
156         [self performSelector:NSSelectorFromString([request.userInfo objectForKey:@"didFinishSelector"]) withObject:request];
157     });
158 }
159
160 - (void)performRequestFailedDelegateInBackground:(ASIPithosRequest *)request {
161     dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^{
162         [self performSelector:NSSelectorFromString([request.userInfo objectForKey:@"didFailSelector"]) withObject:request];
163     });
164 }
165
166 @end