]> err.no Git - scalable-opengroupware.org/blob - SOPE/NGCards/CardGroup.m
git-svn-id: http://svn.opengroupware.org/SOGo/inverse/trunk@1025 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 - (CardElement *) firstChildWithTag: (NSString *) aTag;
236 {
237   Class mappedClass;
238   CardElement *child, *mappedChild;
239   NSArray *existing;
240
241   existing = [self childrenWithTag: aTag];
242   if ([existing count])
243     {
244       child = [existing objectAtIndex: 0];
245       mappedClass = [self classForTag: [aTag uppercaseString]];
246       if (mappedClass)
247         {
248           if ([child isKindOfClass: [CardGroup class]])
249             mappedChild = [(CardGroup *) child groupWithClass: mappedClass];
250           else
251             mappedChild = [child elementWithClass: mappedClass];
252         }
253       else
254         mappedChild = child;
255     }
256   else
257     mappedChild = nil;
258
259   return mappedChild;
260 }
261
262 - (void) addChildren: (NSArray *) someChildren
263 {
264   CardElement *currentChild;
265   NSEnumerator *newChildren;
266
267   newChildren = [someChildren objectEnumerator];
268   currentChild = [newChildren nextObject];
269   while (currentChild)
270     {
271       [self addChild: currentChild];
272       currentChild = [newChildren nextObject];
273     }
274 }
275
276 - (NSArray *) children
277 {
278   return children;
279 }
280
281 - (NSArray *) childrenWithTag: (NSString *) aTag
282 {
283   return [children cardElementsWithTag: aTag];
284 }
285
286 - (NSArray *) childrenWithAttribute: (NSString *) anAttribute
287                         havingValue: (NSString *) aValue
288 {
289   return [children cardElementsWithAttribute: anAttribute
290                    havingValue: aValue];
291 }
292
293 - (NSArray *) childrenWithTag: (NSString *) aTag
294                  andAttribute: (NSString *) anAttribute
295                   havingValue: (NSString *) aValue
296 {
297   NSArray *elements;
298
299   elements = [self childrenWithTag: aTag];
300
301   return [elements cardElementsWithAttribute: anAttribute
302                    havingValue: aValue];
303 }
304
305 - (NSArray *) childrenGroupWithTag: (NSString *) aTag
306                          withChild: (NSString *) aChild
307                  havingSimpleValue: (NSString *) aValue
308 {
309   NSEnumerator *allElements;
310   NSMutableArray *elements;
311   CardGroup *element;
312   NSString *value;
313
314   elements = [NSMutableArray new];
315   [elements autorelease];
316
317   allElements = [[self childrenWithTag: aTag] objectEnumerator];
318   element = [allElements nextObject];
319   while (element)
320     {
321       if ([element isKindOfClass: [CardGroup class]])
322         {
323           value = [[element uniqueChildWithTag: aChild] value: 0];
324           if ([value isEqualToString: aValue])
325             [elements addObject: element];
326         }
327       element = [allElements nextObject];
328     }
329
330   return elements;
331 }
332
333 #warning should be renamed to elementWithClass...
334 - (CardGroup *) groupWithClass: (Class) groupClass
335 {
336   CardGroup *newGroup;
337
338   if ([self isKindOfClass: groupClass])
339     newGroup = self;
340   else
341     {
342       newGroup = (CardGroup *) [self elementWithClass: groupClass];
343       [newGroup setChildrenAsCopy: children];
344     }
345
346   return newGroup;
347 }
348
349 - (void) setChildrenAsCopy: (NSMutableArray *) someChildren
350 {
351   [children release];
352   children = someChildren;
353   [children retain];
354 }
355
356 - (void) addChildWithTag: (NSString *) aTag
357                    types: (NSArray *) someTypes
358              singleValue: (NSString *) aValue
359 {
360   CardElement *newChild;
361   NSEnumerator *types;
362   NSString *type;
363
364   newChild = [CardElement simpleElementWithTag: aTag value: aValue];
365   types = [someTypes objectEnumerator];
366   type = [types nextObject];
367   while (type)
368     {
369       [newChild addType: type];
370       type = [types nextObject];
371     }
372
373   [self addChild: newChild];
374 }
375
376 - (NSString *) description
377 {
378   NSMutableString *str;
379   unsigned int count, max;
380
381   str = [NSMutableString stringWithCapacity:64];
382   [str appendFormat:@"<%p[%@]:%@",
383        self, NSStringFromClass([self class]), [self tag]];
384   max = [children count];
385   if (max > 0)
386     {
387       [str appendFormat: @"\n  %d children: {\n", [children count]];
388       for (count = 0; count < max; count++)
389         [str appendFormat: @"  %@\n",
390              [[children objectAtIndex: count] description]];
391       [str appendFormat: @"}"];
392     }
393   [str appendString:@">"];
394
395   return str;
396 }
397
398 - (void) replaceThisElement: (CardElement *) oldElement
399                 withThisOne: (CardElement *) newElement
400 {
401   unsigned int index;
402
403   index = [children indexOfObject: oldElement];
404   if (index != NSNotFound)
405     [children replaceObjectAtIndex: index withObject: newElement];
406 }
407
408 - (id) copyWithZone: (NSZone *) aZone
409 {
410   CardGroup *new;
411
412   new = [super copyWithZone: aZone];
413   [new setChildrenAsCopy: [children copyWithZone: aZone]];
414
415   return new;
416 }
417
418 @end