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 <SaxObjC/SaxObjC.h>
24 #include "iCalEntityObject.h"
27 @interface iCalCalendar(Privates)
28 - (void)addToEvents:(iCalEvent *)_event;
29 - (void)addToTimezones:(id)_tz;
30 - (void)addToTodos:(iCalToDo *)_todo;
31 - (void)addToJournals:(iCalJournal *)_obj;
32 - (void)addToFreeBusys:(iCalFreeBusy *)_obj;
35 @implementation iCalCalendar
37 static id<NSObject,SaxXMLReader> parser = nil; // THREAD
38 static SaxObjectDecoder *sax = nil; // THREAD
40 + (id<NSObject,SaxXMLReader>)iCalParser {
42 sax = [[SaxObjectDecoder alloc] initWithMappingNamed:@"NGiCal"];;
44 NSLog(@"ERROR(%s): could not create iCal SAX handler!",
48 if (sax != nil && parser == nil) {
50 [[[SaxXMLReaderFactory standardXMLReaderFactory]
51 createXMLReaderForMimeType:@"text/calendar"]
54 NSLog(@"ERROR(%s): did not find a parser for text/calendar!",
59 [parser setContentHandler:sax];
60 [parser setErrorHandler:sax];
65 + (iCalCalendar *)parseCalendarFromSource:(id)_src {
66 static id<NSObject,SaxXMLReader> parser;
69 if ((parser = [self iCalParser]) == nil)
72 [parser parseFromSource:_src];
73 root = [[sax rootObject] retain];
78 if ([root isKindOfClass:self])
79 return [root autorelease];
81 if (![root isKindOfClass:[iCalEntityObject class]]) {
82 NSLog(@"ERROR(%s): parsed object is of an unexpected class %@: %@",
83 __PRETTY_FUNCTION__, NSStringFromClass([root class]), root);
88 /* so we just got an iCalEntityObject, wrap that manually into a cal */
89 cal = [[[self alloc] initWithEntityObject:root] autorelease];
90 [root release]; root = nil;
94 - (id)initWithEntityObject:(iCalEntityObject *)_entityObject {
95 if ((self = [self init])) {
96 if ([_entityObject isKindOfClass:[iCalEvent class]])
97 [self addToEvents:(iCalEvent *)_entityObject];
98 else if ([_entityObject isKindOfClass:[iCalToDo class]])
99 [self addToTodos:(iCalToDo *)_entityObject];
100 else if ([_entityObject isKindOfClass:[iCalJournal class]])
101 [self addToJournals:(iCalJournal *)_entityObject];
102 else if ([_entityObject isKindOfClass:[iCalFreeBusy class]])
103 [self addToFreeBusys:(iCalFreeBusy *)_entityObject];
104 else if ([_entityObject isNotNull]) {
105 [self errorWithFormat:@"Unexpected entity object: %@", _entityObject];
114 [self->version release];
115 [self->calscale release];
116 [self->prodId release];
117 [self->method release];
119 [self->todos release];
120 [self->events release];
121 [self->journals release];
122 [self->freeBusys release];
123 [self->timezones release];
129 - (id)copyWithZone:(NSZone *)_zone {
132 new = [super copyWithZone:_zone];
134 ASSIGNCOPY(new->version, self->version);
135 ASSIGNCOPY(new->calscale, self->calscale);
136 ASSIGNCOPY(new->prodId, self->prodId);
137 ASSIGNCOPY(new->method, self->method);
139 ASSIGNCOPY(new->todos, self->todos);
140 ASSIGNCOPY(new->events, self->events);
141 ASSIGNCOPY(new->journals, self->journals);
142 ASSIGNCOPY(new->freeBusys, self->freeBusys);
143 ASSIGNCOPY(new->timezones, self->timezones);
150 - (void)setCalscale:(NSString *)_value {
151 ASSIGNCOPY(self->calscale, _value);
153 - (NSString *)calscale {
154 return self->calscale;
156 - (void)setVersion:(NSString *)_value {
157 ASSIGNCOPY(self->version, _value);
159 - (NSString *)version {
160 return self->version;
162 - (void)setProdId:(NSString *)_value {
163 ASSIGNCOPY(self->prodId, _value);
165 - (NSString *)prodId {
168 - (void)setMethod:(NSString *)_method {
169 ASSIGNCOPY(self->method, _method);
171 - (NSString *)method {
175 - (void)addToEvents:(iCalEvent *)_event {
176 if (_event == nil) return;
177 if (self->events == nil)
178 self->events = [[NSMutableArray alloc] initWithCapacity:4];
179 [self->events addObject:_event];
181 - (NSArray *)events {
185 - (void)addToTimezones:(id)_tz {
188 if (_tz == nil) return;
189 if (self->timezones == nil)
190 self->timezones = [[NSMutableDictionary alloc] initWithCapacity:4];
192 if ((tzid = [_tz valueForKey:@"tzid"]) == nil) {
193 [self logWithFormat:@"ERROR: missing timezone-id in timezone: %@", _tz];
196 [self->timezones setObject:_tz forKey:tzid];
198 - (NSArray *)timezones {
199 return [self->timezones allValues];
202 - (void)addToTodos:(iCalToDo *)_todo {
203 if (_todo == nil) return;
204 if (self->todos == nil)
205 self->todos = [[NSMutableArray alloc] initWithCapacity:4];
206 [self->todos addObject:_todo];
212 - (void)addToJournals:(iCalJournal *)_obj {
213 if (_obj == nil) return;
214 if (self->journals == nil)
215 self->journals = [[NSMutableArray alloc] initWithCapacity:4];
216 [self->journals addObject:_obj];
218 - (NSArray *)journals {
219 return self->journals;
222 - (void)addToFreeBusys:(iCalFreeBusy *)_obj {
223 if (_obj == nil) return;
224 if (self->freeBusys == nil)
225 self->freeBusys = [[NSMutableArray alloc] initWithCapacity:4];
226 [self->freeBusys addObject:_obj];
228 - (NSArray *)freeBusys {
229 return self->freeBusys;
234 - (NSArray *)allObjects {
237 ma = [NSMutableArray arrayWithCapacity:32];
238 if (self->events) [ma addObjectsFromArray:self->events];
239 if (self->todos) [ma addObjectsFromArray:self->todos];
240 if (self->freeBusys) [ma addObjectsFromArray:self->freeBusys];
241 if (self->journals) [ma addObjectsFromArray:self->journals];
244 - (NSEnumerator *)objectEnumerator {
245 return [[self allObjects] objectEnumerator];
250 - (NSString *)entityName {
256 - (NSString *)description {
259 ms = [NSMutableString stringWithCapacity:128];
260 [ms appendFormat:@"<0x%08X[%@]:", self, NSStringFromClass([self class])];
262 if (self->version) [ms appendFormat:@" v%@", self->version];
263 if (self->method) [ms appendFormat:@" method=%@", self->method];
264 if (self->prodId) [ms appendFormat:@" product=%@", self->prodId];
265 if (self->calscale) [ms appendFormat:@" calscale=%@", self->calscale];
267 if ([self->events count] > 0)
268 [ms appendFormat:@" events=%@", self->events];
269 if ([self->todos count] > 0)
270 [ms appendFormat:@" todos=%@", self->todos];
271 if ([self->freeBusys count] > 0)
272 [ms appendFormat:@" fb=%@", self->freeBusys];
273 if ([self->journals count] > 0)
274 [ms appendFormat:@" journals=%@", self->journals];
276 if ([self->timezones count] > 0)
277 [ms appendFormat:@" tzs=%@", [self->timezones allKeys]];
279 [ms appendString:@">"];
283 @end /* iCalCalendar */