]> err.no Git - sope/blob - sope-ical/NGiCal/IcalElements.m
fixed library version
[sope] / sope-ical / NGiCal / IcalElements.m
1 /*
2   Copyright (C) 2000-2004 SKYRIX Software AG
3
4   This file is part of OpenGroupware.org.
5
6   OGo 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   OGo 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 OGo; 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 // $Id$
22
23 #include <NGObjWeb/WODynamicElement.h>
24
25 @interface IcalComponent : WODynamicElement
26 {
27   WOAssociation *cname;
28   WOElement     *template;
29 }
30 @end
31
32 @interface IcalProperty : WODynamicElement
33 {
34   WOAssociation *pname;
35   WOElement     *template;
36   NSDictionary  *parameters;
37   WOAssociation *value;
38   WOAssociation *valueType;
39 }
40 @end
41
42 #include "common.h"
43
44 static inline NSDictionary *ExtractParameters(NSDictionary *_set) {
45   /* extracts ? parameters */
46   NSMutableDictionary *paras = nil;
47   NSMutableArray      *paraKeys = nil;
48   NSEnumerator        *keys;
49   NSString            *key;
50   
51   // locate query parameters
52   keys = [_set keyEnumerator];
53   while ((key = [keys nextObject])) {
54     if ([key hasPrefix:@"?"]) {
55       WOAssociation *value;
56
57       if ([key isEqualToString:@"?wosid"])
58         continue;
59
60       value = [_set objectForKey:key];
61           
62       if (paraKeys == nil)
63         paraKeys = [NSMutableArray arrayWithCapacity:8];
64       if (paras == nil)
65         paras = [NSMutableDictionary dictionaryWithCapacity:8];
66           
67       [paraKeys addObject:key];
68       [paras setObject:value forKey:[key substringFromIndex:1]];
69     }
70   }
71
72   // remove query parameters
73   if (paraKeys) {
74     unsigned cnt, count;
75     for (cnt = 0, count = [paraKeys count]; cnt < count; cnt++) {
76       [(NSMutableDictionary *)_set removeObjectForKey:
77                                      [paraKeys objectAtIndex:cnt]];
78     }
79   }
80
81   // assign parameters
82   return [paras copy];
83 }
84
85 static inline id GetProperty(NSDictionary *_set, NSString *_name) {
86   id propValue = [_set objectForKey:_name];
87
88   if (propValue) {
89     propValue = RETAIN(propValue);
90     [(id)_set removeObjectForKey:_name];
91   }
92   return propValue;
93 }
94
95 @implementation IcalComponent
96
97 - (id)initWithName:(NSString *)_name
98   associations:(NSDictionary *)_config
99   template:(WOElement *)_t
100 {
101   if ((self = [super initWithName:_name associations:_config template:_t])) {
102     self->cname = GetProperty(_config, @"name");
103     self->template = RETAIN(_t);
104   }
105   return self;
106 }
107
108 - (void)dealloc {
109   RELEASE(self->template);
110   RELEASE(self->cname);
111   [super dealloc];
112 }
113
114 - (void)appendToResponse:(WOResponse *)_response inContext:(WOContext *)_ctx {
115   NSString *n;
116   
117   n = [self->cname stringValueInComponent:[_ctx component]];
118   
119   [_response appendContentString:@"BEGIN:"];
120   [_response appendContentString:n];
121   [self->template appendToResponse:_response inContext:_ctx];
122   [_response appendContentString:@"END:"];
123   [_response appendContentString:n];
124 }
125
126 @end /* IcalComponent */
127
128 @implementation IcalProperty
129
130 - (id)initWithName:(NSString *)_name
131   associations:(NSDictionary *)_config
132   template:(WOElement *)_t
133 {
134   if ((self = [super initWithName:_name associations:_config template:_t])) {
135     self->pname      = GetProperty(_config, @"name");
136     self->value      = GetProperty(_config, @"value");
137     self->valueType  = GetProperty(_config, @"valueType");
138     self->template   = RETAIN(_t);
139     self->parameters = ExtractParameters(_config);
140   }
141   return self;
142 }
143
144 - (void)dealloc {
145   RELEASE(self->value);
146   RELEASE(self->valueType);
147   RELEASE(self->parameters);
148   RELEASE(self->template);
149   RELEASE(self->pname);
150   [super dealloc];
151 }
152
153 - (void)appendToResponse:(WOResponse *)_response inContext:(WOContext *)_ctx {
154   WOComponent  *sComponent;
155   NSString     *n;
156   NSEnumerator *keys;
157   NSString     *key;
158   id           val;
159   NSString     *valType;
160
161   sComponent = [_ctx component];
162   n       = [self->pname     stringValueInComponent:sComponent];
163   val     = [self->value     valueInComponent:sComponent];
164   valType = [self->valueType stringValueInComponent:sComponent];
165
166   /* add name */
167   [_response appendContentString:n];
168
169   /* add parameters */
170   keys = [self->parameters keyEnumerator];
171   while ((key = [keys nextObject])) {
172     WOAssociation *val;
173     NSString *s;
174     
175     val = [self->parameters objectForKey:key];
176     s   = [val stringValueInComponent:sComponent];
177     
178     if ([s length] > 0) {
179       [_response appendContentString:@";"];
180       [_response appendContentString:key];
181       [_response appendContentString:@"="];
182       [_response appendContentString:s];
183     }
184   }
185   
186   /* add value */
187   [_response appendContentString:@":"];
188
189   if ([valType length] == 0) {
190     val = [val stringValue];
191   }
192   else if ([valType isEqualToString:@"datetime"]) {
193     static NSString *calfmt = @"%Y%m%dT%H%M00Z";
194     
195     if ([val respondsToSelector:@selector(descriptionWithCalendarFormat:)]) {
196       static NSTimeZone *gmt = nil;
197       if (gmt == nil) gmt = [NSTimeZone timeZoneWithAbbreviation:@"GMT"];
198       [val setTimeZone:gmt];
199       val = [val descriptionWithCalendarFormat:calfmt];
200     }
201     else
202       val = [val stringValue];
203   }
204   else
205     val = [val stringValue];
206   
207   [_response appendContentString:val];
208   [self->template appendToResponse:_response inContext:_ctx];
209 }
210
211 @end /* IcalProperty */