]> err.no Git - scalable-opengroupware.org/blob - SOPE/NGCards/CardGroup.m
git-svn-id: http://svn.opengroupware.org/SOGo/inverse/trunk@1021 d1b88da0-ebda-0310...
[scalable-opengroupware.org] / SOPE / NGCards / CardGroup.m
1 /* CardGroup.m - this file is part of SOPE
2  *
3  * Copyright (C) 2006 Inverse groupe conseil
4  *
5  * Author: Wolfgang Sourdeau <wsourdeau@inverse.ca>
6  *
7  * This file is free software; you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License as published by
9  * the Free Software Foundation; either version 2, or (at your option)
10  * any later version.
11  *
12  * This file is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program; see the file COPYING.  If not, write to
19  * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
20  * Boston, MA 02111-1307, USA.
21  */
22
23 #import <Foundation/NSArray.h>
24 #import <Foundation/NSDictionary.h>
25 #import <Foundation/NSString.h>
26 #import <SaxObjC/SaxXMLReader.h>
27 #import <SaxObjC/SaxXMLReaderFactory.h>
28
29 #import "NGCardsSaxHandler.h"
30 #import "NSArray+NGCards.h"
31
32 #import "CardGroup.h"
33
34 static id<NSObject,SaxXMLReader> parser = nil;
35 static NGCardsSaxHandler *sax = nil;
36
37 @implementation CardGroup
38
39 + (id<NSObject,SaxXMLReader>) cardParser
40 {
41   if (!sax)
42     sax = [NGCardsSaxHandler new];
43   
44   if (!parser)
45     {
46 #if 1
47       parser = [[SaxXMLReaderFactory standardXMLReaderFactory]
48                  createXMLReaderWithName: @"VSCardSaxDriver"];
49       [parser retain];
50 #else
51       parser =
52         [[[SaxXMLReaderFactory standardXMLReaderFactory] 
53            createXMLReaderForMimeType:@"text/x-vcard"] retain];
54 #endif
55       if (parser)
56         {
57           [parser setContentHandler:sax];
58           [parser setErrorHandler:sax];
59         }
60       else
61         NSLog(@"ERROR(%s): did not find a parser for text/x-vcard!",
62               __PRETTY_FUNCTION__);
63     }
64   
65   return parser;
66 }
67
68 + (NSArray *) parseFromSource: (id) source
69 {
70   static id <NSObject,SaxXMLReader> cardParser;
71   NSMutableArray *cardGroups;
72   NSEnumerator *cards;
73   CardGroup *currentCard;
74
75   cardParser = [self cardParser];
76   [sax setTopElementClass: [self class]];
77
78   if (parser)
79     {
80       cardGroups = [NSMutableArray new];
81       [cardGroups autorelease];
82       
83       [parser parseFromSource: source];
84       cards = [[sax cards] objectEnumerator];
85
86       currentCard = [cards nextObject];
87       while (currentCard)
88         {
89           [cardGroups addObject: currentCard];
90           currentCard = [cards nextObject];
91         }
92     }
93   else
94     cardGroups = nil;
95
96   return cardGroups;
97 }
98
99 + (id) parseSingleFromSource: (id) source
100 {
101   NSArray *cards;
102   CardGroup *card;
103
104   cards = [self parseFromSource: source];
105   if (cards && [cards count])
106     card = [cards objectAtIndex: 0];
107   else
108     card = nil;
109
110   return card;
111 }
112
113 + (id) groupWithTag: (NSString *) aTag
114 {
115   id newGroup;
116
117   newGroup = [self new];
118   [newGroup autorelease];
119   [newGroup setTag: aTag];
120
121   return newGroup;
122 }
123
124 + (id) groupWithTag: (NSString *) aTag
125            children: (NSArray *) someChildren
126 {
127   id newGroup;
128
129   newGroup = [self new];
130   [newGroup autorelease];
131   [newGroup setTag: aTag];
132   [newGroup addChildren: someChildren];
133
134   return newGroup;
135 }
136
137 - (id) init
138 {
139   if ((self = [super init]))
140     {
141       children = [NSMutableArray new];
142     }
143
144   return self;
145 }
146
147 - (void) dealloc
148 {
149   [children release];
150   [super dealloc];
151 }
152
153 - (Class) classForTag: (NSString *) tagClass
154 {
155   NSLog (@"class '%@': '%@'", NSStringFromClass([self class]),
156          tagClass);
157
158   return nil;
159 }
160
161 - (void) addChild: (CardElement *) aChild
162 {
163   Class mappedClass;
164   NSString *childTag;
165   CardElement *newChild;
166
167   childTag = [aChild tag];
168   newChild = nil;
169   mappedClass = [self classForTag: [childTag uppercaseString]];
170   if (mappedClass)
171     {
172       if (![aChild isKindOfClass: mappedClass])
173         {
174           NSLog (@"warning: new child to entity '%@': '%@' converted to '%@'",
175                  tag, childTag, NSStringFromClass(mappedClass));
176           if ([aChild isKindOfClass: [CardGroup class]])
177             newChild = [(CardGroup *) aChild groupWithClass: mappedClass];
178           else
179             newChild = [aChild elementWithClass: mappedClass];
180         }
181     }
182   else
183     NSLog (@"warning: no mapped class for tag '%@'",
184            childTag);
185
186   if (!newChild)
187     newChild = aChild;
188   [children addObject: newChild];
189   [newChild setParent: self];
190 }
191
192 - (CardElement *) uniqueChildWithTag: (NSString *) aTag
193 {
194   NSArray *existing;
195   Class elementClass;
196   CardElement *uniqueChild;
197
198   existing = [self childrenWithTag: aTag];
199   if ([existing count] > 0)
200     uniqueChild = [existing objectAtIndex: 0];
201   else
202     {
203       elementClass = [self classForTag: [aTag uppercaseString]];
204       if (!elementClass)
205         elementClass = [CardElement class];
206
207       uniqueChild = [elementClass new];
208       [uniqueChild autorelease];
209       [uniqueChild setTag: aTag];
210       [self addChild: uniqueChild];
211     }
212
213   return uniqueChild;
214 }
215
216 - (void) setUniqueChild: (CardElement *) aChild
217 {
218   CardElement *currentChild;
219   NSString *childTag;
220   NSEnumerator *existing;
221
222   childTag = [aChild tag];
223   existing = [[self childrenWithTag: childTag] objectEnumerator];
224
225   currentChild = [existing nextObject];
226   while (currentChild)
227     {
228       [children removeObject: currentChild];
229       currentChild = [existing nextObject];
230     }
231
232   [self addChild: aChild];
233 }
234
235 - (void) addChildren: (NSArray *) someChildren
236 {
237   CardElement *currentChild;
238   NSEnumerator *newChildren;
239
240   newChildren = [someChildren objectEnumerator];
241   currentChild = [newChildren nextObject];
242   while (currentChild)
243     {
244       [self addChild: currentChild];
245       currentChild = [newChildren nextObject];
246     }
247 }
248
249 - (NSArray *) children
250 {
251   return children;
252 }
253
254 - (NSArray *) childrenWithTag: (NSString *) aTag
255 {
256   return [children cardElementsWithTag: aTag];
257 }
258
259 - (NSArray *) childrenWithAttribute: (NSString *) anAttribute
260                         havingValue: (NSString *) aValue
261 {
262   return [children cardElementsWithAttribute: anAttribute
263                    havingValue: aValue];
264 }
265
266 - (NSArray *) childrenWithTag: (NSString *) aTag
267                  andAttribute: (NSString *) anAttribute
268                   havingValue: (NSString *) aValue
269 {
270   NSArray *elements;
271
272   elements = [self childrenWithTag: aTag];
273
274   return [elements cardElementsWithAttribute: anAttribute
275                    havingValue: aValue];
276 }
277
278 - (NSArray *) childrenGroupWithTag: (NSString *) aTag
279                          withChild: (NSString *) aChild
280                  havingSimpleValue: (NSString *) aValue
281 {
282   NSEnumerator *allElements;
283   NSMutableArray *elements;
284   CardGroup *element;
285   NSString *value;
286
287   elements = [NSMutableArray new];
288   [elements autorelease];
289
290   allElements = [[self childrenWithTag: aTag] objectEnumerator];
291   element = [allElements nextObject];
292   while (element)
293     {
294       if ([element isKindOfClass: [CardGroup class]])
295         {
296           value = [[element uniqueChildWithTag: aChild] value: 0];
297           if ([value isEqualToString: aValue])
298             [elements addObject: element];
299         }
300       element = [allElements nextObject];
301     }
302
303   return elements;
304 }
305
306 #warning should be renamed to elementWithClass...
307 - (CardGroup *) groupWithClass: (Class) groupClass
308 {
309   CardGroup *newGroup;
310
311   if ([self isKindOfClass: groupClass])
312     newGroup = self;
313   else
314     {
315       newGroup = (CardGroup *) [self elementWithClass: groupClass];
316       [newGroup setChildrenAsCopy: children];
317     }
318
319   return newGroup;
320 }
321
322 - (void) setChildrenAsCopy: (NSMutableArray *) someChildren
323 {
324   [children release];
325   children = someChildren;
326   [children retain];
327 }
328
329 - (void) addChildWithTag: (NSString *) aTag
330                    types: (NSArray *) someTypes
331              singleValue: (NSString *) aValue
332 {
333   CardElement *newChild;
334   NSEnumerator *types;
335   NSString *type;
336
337   newChild = [CardElement simpleElementWithTag: aTag value: aValue];
338   types = [someTypes objectEnumerator];
339   type = [types nextObject];
340   while (type)
341     {
342       [newChild addType: type];
343       type = [types nextObject];
344     }
345
346   [self addChild: newChild];
347 }
348
349 - (NSString *) description
350 {
351   NSMutableString *str;
352   unsigned int count, max;
353
354   str = [NSMutableString stringWithCapacity:64];
355   [str appendFormat:@"<%p[%@]:%@",
356        self, NSStringFromClass([self class]), [self tag]];
357   max = [children count];
358   if (max > 0)
359     {
360       [str appendFormat: @"\n  %d children: {\n", [children count]];
361       for (count = 0; count < max; count++)
362         [str appendFormat: @"  %@\n",
363              [[children objectAtIndex: count] description]];
364       [str appendFormat: @"}"];
365     }
366   [str appendString:@">"];
367
368   return str;
369 }
370
371 - (void) replaceThisElement: (CardElement *) oldElement
372                 withThisOne: (CardElement *) newElement
373 {
374   unsigned int index;
375
376   index = [children indexOfObject: oldElement];
377   if (index != NSNotFound)
378     [children replaceObjectAtIndex: index withObject: newElement];
379 }
380
381 - (id) copyWithZone: (NSZone *) aZone
382 {
383   CardGroup *new;
384
385   new = [super copyWithZone: aZone];
386   [new setChildrenAsCopy: [children copyWithZone: aZone]];
387
388   return new;
389 }
390
391 @end