2 Copyright (C) 2000-2005 SKYRIX Software AG
4 This file is part of SOPE.
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
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.
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
22 #include "iCalCalendar.h"
23 #include "iCalEvent.h"
25 #include "iCalJournal.h"
26 #include "iCalFreeBusy.h"
27 #include "iCalEntityObject.h"
28 #include <SaxObjC/SaxObjC.h>
31 @interface iCalCalendar(Privates)
32 - (void)addToEvents:(iCalEvent *)_event;
33 - (void)addToTimezones:(id)_tz;
34 - (void)addToTodos:(iCalToDo *)_todo;
35 - (void)addToJournals:(iCalJournal *)_obj;
36 - (void)addToFreeBusys:(iCalFreeBusy *)_obj;
39 @implementation iCalCalendar
41 static id<NSObject,SaxXMLReader> parser = nil; // THREAD
42 static SaxObjectDecoder *sax = nil; // THREAD
45 return [super version] + 0 /* v0 */;
48 NSAssert2([super version] == 0,
49 @"invalid superclass (%@) version %i !",
50 NSStringFromClass([self superclass]), [super version]);
53 + (id<NSObject,SaxXMLReader>)iCalParser {
55 sax = [[SaxObjectDecoder alloc] initWithMappingNamed:@"NGiCal"];;
57 NSLog(@"ERROR(%s): could not create iCal SAX handler!",
61 if (sax != nil && parser == nil) {
63 [[[SaxXMLReaderFactory standardXMLReaderFactory]
64 createXMLReaderForMimeType:@"text/calendar"]
67 NSLog(@"ERROR(%s): did not find a parser for text/calendar!",
72 [parser setContentHandler:sax];
73 [parser setErrorHandler:sax];
78 + (iCalCalendar *)parseCalendarFromSource:(id)_src {
79 static id<NSObject,SaxXMLReader> parser;
82 if ((parser = [self iCalParser]) == nil)
85 [parser parseFromSource:_src];
86 root = [[sax rootObject] retain];
91 if ([root isKindOfClass:self])
92 return [root autorelease];
94 if (![root isKindOfClass:[iCalEntityObject class]]) {
95 NSLog(@"ERROR(%s): parsed object is of an unexpected class %@: %@",
96 __PRETTY_FUNCTION__, NSStringFromClass([root class]), root);
101 /* so we just got an iCalEntityObject, wrap that manually into a cal */
102 cal = [[[self alloc] initWithEntityObject:root] autorelease];
103 [root release]; root = nil;
107 - (id)initWithEntityObject:(iCalEntityObject *)_entityObject {
108 if ((self = [self init])) {
109 if ([_entityObject isKindOfClass:[iCalEvent class]])
110 [self addToEvents:(iCalEvent *)_entityObject];
111 else if ([_entityObject isKindOfClass:[iCalToDo class]])
112 [self addToTodos:(iCalToDo *)_entityObject];
113 else if ([_entityObject isKindOfClass:[iCalJournal class]])
114 [self addToJournals:(iCalJournal *)_entityObject];
115 else if ([_entityObject isKindOfClass:[iCalFreeBusy class]])
116 [self addToFreeBusys:(iCalFreeBusy *)_entityObject];
117 else if ([_entityObject isNotNull]) {
118 [self errorWithFormat:@"Unexpected entity object: %@", _entityObject];
127 [self->version release];
128 [self->calscale release];
129 [self->prodId release];
130 [self->method release];
132 [self->todos release];
133 [self->events release];
134 [self->journals release];
135 [self->freeBusys release];
136 [self->timezones release];
142 - (id)copyWithZone:(NSZone *)_zone {
145 new = [super copyWithZone:_zone];
147 new->version = [self->version copyWithZone:_zone];
148 new->calscale = [self->calscale copyWithZone:_zone];
149 new->prodId = [self->prodId copyWithZone:_zone];
150 new->method = [self->method copyWithZone:_zone];
152 new->todos = [self->todos copyWithZone:_zone];
153 new->events = [self->events copyWithZone:_zone];
154 new->journals = [self->journals copyWithZone:_zone];
155 new->freeBusys = [self->freeBusys copyWithZone:_zone];
156 new->timezones = [self->timezones copyWithZone:_zone];
163 - (void)setCalscale:(NSString *)_value {
164 ASSIGNCOPY(self->calscale, _value);
166 - (NSString *)calscale {
167 return self->calscale;
169 - (void)setVersion:(NSString *)_value {
170 ASSIGNCOPY(self->version, _value);
172 - (NSString *)version {
173 return self->version;
175 - (void)setProdId:(NSString *)_value {
176 ASSIGNCOPY(self->prodId, _value);
178 - (NSString *)prodId {
181 - (void)setMethod:(NSString *)_method {
182 ASSIGNCOPY(self->method, _method);
184 - (NSString *)method {
188 - (void)addToEvents:(iCalEvent *)_event {
189 if (_event == nil) return;
190 if (self->events == nil)
191 self->events = [[NSMutableArray alloc] initWithCapacity:4];
192 [self->events addObject:_event];
194 - (NSArray *)events {
198 - (void)addToTimezones:(id)_tz {
201 if (_tz == nil) return;
202 if (self->timezones == nil)
203 self->timezones = [[NSMutableDictionary alloc] initWithCapacity:4];
205 if ((tzid = [_tz valueForKey:@"tzid"]) == nil) {
206 [self logWithFormat:@"ERROR: missing timezone-id in timezone: %@", _tz];
209 [self->timezones setObject:_tz forKey:tzid];
211 - (NSArray *)timezones {
212 return [self->timezones allValues];
215 - (void)addToTodos:(iCalToDo *)_todo {
216 if (_todo == nil) return;
217 if (self->todos == nil)
218 self->todos = [[NSMutableArray alloc] initWithCapacity:4];
219 [self->todos addObject:_todo];
225 - (void)addToJournals:(iCalJournal *)_obj {
226 if (_obj == nil) return;
227 if (self->journals == nil)
228 self->journals = [[NSMutableArray alloc] initWithCapacity:4];
229 [self->journals addObject:_obj];
231 - (NSArray *)journals {
232 return self->journals;
235 - (void)addToFreeBusys:(iCalFreeBusy *)_obj {
236 if (_obj == nil) return;
237 if (self->freeBusys == nil)
238 self->freeBusys = [[NSMutableArray alloc] initWithCapacity:4];
239 [self->freeBusys addObject:_obj];
241 - (NSArray *)freeBusys {
242 return self->freeBusys;
247 - (NSArray *)allObjects {
250 ma = [NSMutableArray arrayWithCapacity:32];
251 if (self->events) [ma addObjectsFromArray:self->events];
252 if (self->todos) [ma addObjectsFromArray:self->todos];
253 if (self->freeBusys) [ma addObjectsFromArray:self->freeBusys];
254 if (self->journals) [ma addObjectsFromArray:self->journals];
257 - (NSEnumerator *)objectEnumerator {
258 return [[self allObjects] objectEnumerator];
263 - (NSString *)entityName {
269 - (NSString *)description {
272 ms = [NSMutableString stringWithCapacity:128];
273 [ms appendFormat:@"<0x%08X[%@]:", self, NSStringFromClass([self class])];
275 if (self->version) [ms appendFormat:@" v%@", self->version];
276 if (self->method) [ms appendFormat:@" method=%@", self->method];
277 if (self->prodId) [ms appendFormat:@" product=%@", self->prodId];
278 if (self->calscale) [ms appendFormat:@" calscale=%@", self->calscale];
280 if ([self->events count] > 0)
281 [ms appendFormat:@" events=%@", self->events];
282 if ([self->todos count] > 0)
283 [ms appendFormat:@" todos=%@", self->todos];
284 if ([self->freeBusys count] > 0)
285 [ms appendFormat:@" fb=%@", self->freeBusys];
286 if ([self->journals count] > 0)
287 [ms appendFormat:@" journals=%@", self->journals];
289 if ([self->timezones count] > 0)
290 [ms appendFormat:@" tzs=%@", [self->timezones allKeys]];
292 [ms appendString:@">"];
296 @end /* iCalCalendar */