]> err.no Git - sope/blob - sope-core/NGExtensions/EOExt.subproj/EOCompoundDataSource.m
minor code cleanups
[sope] / sope-core / NGExtensions / EOExt.subproj / EOCompoundDataSource.m
1 /*
2   Copyright (C) 2000-2003 SKYRIX Software AG
3
4   This file is part of OGo
5
6   OGo is free software; you can redistribute it and/or modify it under
7   the terms of the GNU Lesser General Public License as published by the
8   Free Software Foundation; either version 2, or (at your option) any
9   later version.
10
11   OGo is distributed in the hope that it will be useful, but WITHOUT ANY
12   WARRANTY; without even the implied warranty of MERCHANTABILITY or
13   FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
14   License for more details.
15
16   You should have received a copy of the GNU Lesser General Public
17   License along with OGo; see the file COPYING.  If not, write to the
18   Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA
19   02111-1307, USA.
20 */
21 // $Id$
22
23 #include "EOCompoundDataSource.h"
24 #import <EOControl/EOControl.h>
25 #import "EODataSource+NGExtensions.h"
26 #import "common.h"
27
28 @implementation EOCompoundDataSource
29
30 - (id)initWithDataSources:(NSArray *)_ds {
31   if ((self = [super init])) {
32     self->sources = [_ds shallowCopy];
33   }
34   return self;
35 }
36
37 - (void)dealloc {
38   [[NSNotificationCenter defaultCenter] removeObserver:self];
39   [self->sortOrderings      release];
40   [self->auxiliaryQualifier release];
41   [self->sources            release];
42   [super dealloc];
43 }
44
45 /* accessors */
46
47 - (void)setSources:(NSArray *)_sources {
48   if (self->sources != _sources) {
49     _sources = [_sources shallowCopy];
50     [self->sources release];
51     self->sources = _sources;
52     {
53       NSNotificationCenter *nc;
54       NSEnumerator         *enumerator;
55       id                   obj;
56       
57       nc         = [NSNotificationCenter defaultCenter];
58       enumerator = [self->sources objectEnumerator];
59       
60       while ((obj = [enumerator nextObject])) {
61         [nc addObserver:self
62             selector:@selector(postDataSourceChangedNotification)
63             name:EODataSourceDidChangeNotification object:obj];
64       }
65     }
66   }
67   [self postDataSourceChangedNotification];
68 }
69 - (NSArray *)sources {
70   return self->sources;
71 }
72
73 - (void)setAuxiliaryQualifier:(EOQualifier *)_q {
74   ASSIGN(self->auxiliaryQualifier, _q);
75   [self postDataSourceChangedNotification];
76 }
77 - (EOQualifier *)auxiliaryQualifier {
78   return self->auxiliaryQualifier;
79 }
80
81 - (void)setSortOrderings:(NSArray *)_so {
82   if (self->sortOrderings != _so) {
83     _so = [_so shallowCopy];
84     [self->sortOrderings release];
85     self->sortOrderings = _so;
86   }
87   [self postDataSourceChangedNotification];
88 }
89 - (NSArray *)sortOrderings {
90   return self->sortOrderings;
91 }
92
93 /* operations */
94
95 - (NSArray *)fetchObjects {
96   NSArray  *objs;
97   unsigned count;
98
99   if ((count = [[self sources] count]) == 0) {
100     objs = nil;
101   }
102   else if (count == 1)
103     objs = [[[self sources] objectAtIndex:0] fetchObjects];
104   else {
105     NSMutableArray *a;
106     NSEnumerator   *e;
107     EODataSource   *ds;
108     
109     a = nil;
110     e = [[self sources] objectEnumerator];
111     while ((ds = [e nextObject])) {
112       NSArray *o;
113
114       o = [ds fetchObjects];
115       if ([o count] > 0) {
116         if (a == nil)
117           a = [NSMutableArray arrayWithCapacity:[o count]];
118         [a addObjectsFromArray:o];
119       }
120     }
121
122     objs = [[a shallowCopy] autorelease];
123   }
124
125   if (objs == nil)
126     return [NSArray array];
127   
128   if ([self auxiliaryQualifier])
129     objs = [objs filteredArrayUsingQualifier:[self auxiliaryQualifier]];
130   
131   if ([self sortOrderings])
132     objs = [objs sortedArrayUsingKeyOrderArray:[self sortOrderings]];
133   
134   return objs;
135 }
136
137 - (void)insertObject:(id)_obj {
138   unsigned count;
139
140   if ((count = [[self sources] count]) == 0)
141     [super insertObject:_obj];
142   else if (count == 1)
143     [[[self sources] objectAtIndex:0] insertObject:_obj];
144   else {
145     NSEnumerator *e;
146     EODataSource *ds;
147
148     e = [[self sources] objectEnumerator];
149     while ((ds = [e nextObject])) {
150       BOOL didFail = NO;
151       
152       NS_DURING
153         [ds insertObject:_obj];
154       NS_HANDLER
155         didFail = YES;
156       NS_ENDHANDLER;
157       
158       if (!didFail)
159         return;
160     }
161     /* all datasources failed to insert .. */
162     [super insertObject:_obj];
163   }
164   [self postDataSourceChangedNotification];
165 }
166
167 - (void)deleteObject:(id)_obj {
168   unsigned count;
169
170   if ((count = [[self sources] count]) == 0)
171     [super deleteObject:_obj];
172   else if (count == 1)
173     [[[self sources] objectAtIndex:0] deleteObject:_obj];
174   else {
175     NSEnumerator *e;
176     EODataSource *ds;
177
178     e = [[self sources] objectEnumerator];
179     while ((ds = [e nextObject])) {
180       BOOL didFail = NO;
181       
182       NS_DURING
183         [ds deleteObject:_obj];
184       NS_HANDLER
185         didFail = YES;
186       NS_ENDHANDLER;
187       
188       if (!didFail)
189         return;
190     }
191     /* all datasources failed to delete .. */
192     [super deleteObject:_obj];
193   }
194   [self postDataSourceChangedNotification];  
195 }
196
197 - (id)createObject {
198   unsigned count;
199   
200   if ((count = [[self sources] count]) == 0)
201     return [super createObject];
202   else if (count == 1)
203     return [[[self sources] objectAtIndex:0] createObject];
204   else {
205     NSEnumerator *e;
206     EODataSource *ds;
207     
208     e = [[self sources] objectEnumerator];
209     while ((ds = [e nextObject])) {
210       id obj;
211
212       if ((obj = [ds createObject]))
213         return obj;
214     }
215     /* all datasources failed to create .. */
216     return [super createObject];
217   }
218   [self postDataSourceChangedNotification];  
219 }
220
221 - (void)updateObject:(id)_obj {
222   unsigned count;
223
224   if ((count = [[self sources] count]) == 0)
225     [super updateObject:_obj];
226   else if (count == 1)
227     [[[self sources] objectAtIndex:0] updateObject:_obj];
228   else {
229     NSEnumerator *e;
230     EODataSource *ds;
231
232     e = [[self sources] objectEnumerator];
233     while ((ds = [e nextObject])) {
234       BOOL didFail = NO;
235       
236       NS_DURING
237         [ds updateObject:_obj];
238       NS_HANDLER
239         didFail = YES;
240       NS_ENDHANDLER;
241       
242       if (!didFail)
243         return;
244     }
245     /* all datasources failed to update .. */
246     [super updateObject:_obj];
247   }
248   [self postDataSourceChangedNotification];  
249 }
250
251 - (EOClassDescription *)classDescriptionForObjects {
252   unsigned count;
253   NSEnumerator *e;
254   EODataSource *ds;
255   
256   if ((count = [[self sources] count]) == 0)
257     return [super classDescriptionForObjects];
258
259   if (count == 1)
260     return [[[self sources] objectAtIndex:0] classDescriptionForObjects];
261     
262   e = [[self sources] objectEnumerator];
263   while ((ds = [e nextObject])) {
264     EOClassDescription *cd;
265
266     if ((cd = [ds classDescriptionForObjects]))
267       return cd;
268   }
269   /* all datasources failed to create .. */
270   return [super classDescriptionForObjects];
271 }
272
273 @end /* EOCompoundDataSource */