]> err.no Git - sope/blob - sope-core/NGExtensions/EOExt.subproj/EOCompoundDataSource.m
added KV archiving to rule engine
[sope] / sope-core / NGExtensions / EOExt.subproj / EOCompoundDataSource.m
1 /*
2   Copyright (C) 2000-2005 SKYRIX Software AG
3
4   This file is part of SOPE.
5
6   SOPE 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   SOPE 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 SOPE; 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
22 #include "EOCompoundDataSource.h"
23 #import <EOControl/EOControl.h>
24 #import "EODataSource+NGExtensions.h"
25 #import "common.h"
26
27 @implementation EOCompoundDataSource
28
29 - (id)initWithDataSources:(NSArray *)_ds {
30   if ((self = [super init])) {
31     self->sources = [_ds shallowCopy];
32   }
33   return self;
34 }
35
36 - (void)dealloc {
37   [[NSNotificationCenter defaultCenter] removeObserver:self];
38   [self->sortOrderings      release];
39   [self->auxiliaryQualifier release];
40   [self->sources            release];
41   [super dealloc];
42 }
43
44 /* accessors */
45
46 - (void)setSources:(NSArray *)_sources {
47   if (self->sources != _sources) {
48     _sources = [_sources shallowCopy];
49     [self->sources release];
50     self->sources = _sources;
51     {
52       NSNotificationCenter *nc;
53       NSEnumerator         *enumerator;
54       id                   obj;
55       
56       nc         = [NSNotificationCenter defaultCenter];
57       enumerator = [self->sources objectEnumerator];
58       
59       while ((obj = [enumerator nextObject])) {
60         [nc addObserver:self
61             selector:@selector(postDataSourceChangedNotification)
62             name:EODataSourceDidChangeNotification object:obj];
63       }
64     }
65   }
66   [self postDataSourceChangedNotification];
67 }
68 - (NSArray *)sources {
69   return self->sources;
70 }
71
72 - (void)setAuxiliaryQualifier:(EOQualifier *)_q {
73   ASSIGN(self->auxiliaryQualifier, _q);
74   [self postDataSourceChangedNotification];
75 }
76 - (EOQualifier *)auxiliaryQualifier {
77   return self->auxiliaryQualifier;
78 }
79
80 - (void)setSortOrderings:(NSArray *)_so {
81   if (self->sortOrderings != _so) {
82     _so = [_so shallowCopy];
83     [self->sortOrderings release];
84     self->sortOrderings = _so;
85   }
86   [self postDataSourceChangedNotification];
87 }
88 - (NSArray *)sortOrderings {
89   return self->sortOrderings;
90 }
91
92 /* operations */
93
94 - (NSArray *)fetchObjects {
95   NSArray  *objs;
96   unsigned count;
97
98   if ((count = [[self sources] count]) == 0) {
99     objs = nil;
100   }
101   else if (count == 1)
102     objs = [[[self sources] objectAtIndex:0] fetchObjects];
103   else {
104     NSMutableArray *a;
105     NSEnumerator   *e;
106     EODataSource   *ds;
107     
108     a = nil;
109     e = [[self sources] objectEnumerator];
110     while ((ds = [e nextObject])) {
111       NSArray *o;
112
113       o = [ds fetchObjects];
114       if ([o count] > 0) {
115         if (a == nil)
116           a = [NSMutableArray arrayWithCapacity:[o count]];
117         [a addObjectsFromArray:o];
118       }
119     }
120
121     objs = [[a shallowCopy] autorelease];
122   }
123
124   if (objs == nil)
125     return [NSArray array];
126   
127   if ([self auxiliaryQualifier])
128     objs = [objs filteredArrayUsingQualifier:[self auxiliaryQualifier]];
129   
130   if ([self sortOrderings])
131     objs = [objs sortedArrayUsingKeyOrderArray:[self sortOrderings]];
132   
133   return objs;
134 }
135
136 - (void)insertObject:(id)_obj {
137   unsigned count;
138
139   if ((count = [[self sources] count]) == 0)
140     [super insertObject:_obj];
141   else if (count == 1)
142     [[[self sources] objectAtIndex:0] insertObject:_obj];
143   else {
144     NSEnumerator *e;
145     EODataSource *ds;
146
147     e = [[self sources] objectEnumerator];
148     while ((ds = [e nextObject])) {
149       BOOL didFail = NO;
150       
151       NS_DURING
152         [ds insertObject:_obj];
153       NS_HANDLER
154         didFail = YES;
155       NS_ENDHANDLER;
156       
157       if (!didFail)
158         return;
159     }
160     /* all datasources failed to insert .. */
161     [super insertObject:_obj];
162   }
163   [self postDataSourceChangedNotification];
164 }
165
166 - (void)deleteObject:(id)_obj {
167   unsigned count;
168
169   if ((count = [[self sources] count]) == 0)
170     [super deleteObject:_obj];
171   else if (count == 1)
172     [[[self sources] objectAtIndex:0] deleteObject:_obj];
173   else {
174     NSEnumerator *e;
175     EODataSource *ds;
176
177     e = [[self sources] objectEnumerator];
178     while ((ds = [e nextObject])) {
179       BOOL didFail = NO;
180       
181       NS_DURING
182         [ds deleteObject:_obj];
183       NS_HANDLER
184         didFail = YES;
185       NS_ENDHANDLER;
186       
187       if (!didFail)
188         return;
189     }
190     /* all datasources failed to delete .. */
191     [super deleteObject:_obj];
192   }
193   [self postDataSourceChangedNotification];  
194 }
195
196 - (id)createObject {
197   unsigned count;
198   
199   if ((count = [[self sources] count]) == 0)
200     return [super createObject];
201   else if (count == 1)
202     return [[[self sources] objectAtIndex:0] createObject];
203   else {
204     NSEnumerator *e;
205     EODataSource *ds;
206     
207     e = [[self sources] objectEnumerator];
208     while ((ds = [e nextObject])) {
209       id obj;
210
211       if ((obj = [ds createObject]))
212         return obj;
213     }
214     /* all datasources failed to create .. */
215     return [super createObject];
216   }
217   [self postDataSourceChangedNotification];  
218 }
219
220 - (void)updateObject:(id)_obj {
221   unsigned count;
222
223   if ((count = [[self sources] count]) == 0)
224     [super updateObject:_obj];
225   else if (count == 1)
226     [[[self sources] objectAtIndex:0] updateObject:_obj];
227   else {
228     NSEnumerator *e;
229     EODataSource *ds;
230
231     e = [[self sources] objectEnumerator];
232     while ((ds = [e nextObject])) {
233       BOOL didFail = NO;
234       
235       NS_DURING
236         [ds updateObject:_obj];
237       NS_HANDLER
238         didFail = YES;
239       NS_ENDHANDLER;
240       
241       if (!didFail)
242         return;
243     }
244     /* all datasources failed to update .. */
245     [super updateObject:_obj];
246   }
247   [self postDataSourceChangedNotification];  
248 }
249
250 - (EOClassDescription *)classDescriptionForObjects {
251   unsigned count;
252   NSEnumerator *e;
253   EODataSource *ds;
254   
255   if ((count = [[self sources] count]) == 0)
256     return [super classDescriptionForObjects];
257
258   if (count == 1)
259     return [[[self sources] objectAtIndex:0] classDescriptionForObjects];
260     
261   e = [[self sources] objectEnumerator];
262   while ((ds = [e nextObject]) != nil) {
263     EOClassDescription *cd;
264
265     if ((cd = [ds classDescriptionForObjects]) != nil)
266       return cd;
267   }
268   /* all datasources failed to create .. */
269   return [super classDescriptionForObjects];
270 }
271
272 @end /* EOCompoundDataSource */