]> err.no Git - sope/blob - sope-appserver/NGObjWeb/Associations/WOValueAssociation.m
improved SOPE security exceptions
[sope] / sope-appserver / NGObjWeb / Associations / WOValueAssociation.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 "WOValueAssociation.h"
24 #include "common.h"
25
26 // TODO: check whether it makes sense to precalculate int/bool/?? values
27 //       from the object value (add counters on how often these are called)
28
29 @implementation WOValueAssociation
30
31 + (int)version {
32   return [super version] /* v2 */;
33 }
34 + (void)initialize {
35   NSAssert2([super version] == 2,
36             @"invalid superclass (%@) version %i !",
37             NSStringFromClass([self superclass]), [super version]);
38 }
39
40 + (WOAssociation *)associationWithValue:(id)_value {
41   return [[[WOValueAssociation alloc] initWithValue:_value] autorelease];
42 }
43
44 - (id)init {
45   return [self initWithValue:nil];
46 }
47 - (id)initWithValue:(id)_value {
48   if ((self = [super init])) {
49     self->value = [_value retain]; /* do not use copy, can be full objects */
50   }
51   return self;
52 }
53 - (id)initWithString:(NSString *)_s {
54   return [self initWithValue:_s];
55 }
56
57 - (void)dealloc {
58   [self->value release];
59   [super dealloc];
60 }
61
62 /* value */
63
64 - (void)setValue:(id)_value inComponent:(WOComponent *)_component {
65   // not settable
66   [NSException raise:@"AssociationException"
67                format:@"association value is not settable !"];
68 }
69 - (id)valueInComponent:(WOComponent *)_component {
70   return self->value;
71 }
72
73 - (BOOL)isValueConstant {
74   return YES;
75 }
76 - (BOOL)isValueSettable {
77   return NO;
78 }
79
80 /* special values */
81
82 - (unsigned int)unsignedIntValueInComponent:(WOComponent *)_component {
83   register unsigned int val;
84   
85   if (self->cacheFlags.hasSmallValue)
86     return self->cacheFlags.smallValue;
87   
88   val = [self->value unsignedIntValue];
89   if (self->cacheFlags.hasNoSmallValue)
90     return val;
91   
92   if (val < 65536) {
93     self->cacheFlags.smallValue = val;
94     self->cacheFlags.hasSmallValue = 1;
95   }
96   else
97     self->cacheFlags.hasNoSmallValue = 1;
98   return val;
99 }
100 - (int)intValueInComponent:(WOComponent *)_component {
101   register int val;
102   
103   if (self->cacheFlags.hasSmallValue)
104     return self->cacheFlags.smallValue;
105   
106   val = [self->value intValue];
107   if (self->cacheFlags.hasNoSmallValue)
108     return val;
109   
110   if (val >= 0 && val < 65536) {
111     self->cacheFlags.smallValue = val;
112     self->cacheFlags.hasSmallValue = 1;
113   }
114   else
115     self->cacheFlags.hasNoSmallValue = 1;
116   return val;
117 }
118 - (BOOL)boolValueInComponent:(WOComponent *)_component {
119   switch (self->cacheFlags.boolValue) {
120   case 1: return YES;
121   case 2: return NO;
122   default:
123     self->cacheFlags.boolValue = [self->value boolValue] ? 1 : 2;
124     return self->cacheFlags.boolValue == 1 ? YES : NO;
125   }
126 }
127 - (NSString *)stringValueInComponent:(WOComponent *)_component {
128   return [self->value stringValue];
129 }
130
131 /* NSCoding */
132
133 - (void)encodeWithCoder:(NSCoder *)_coder {
134   [_coder encodeObject:self->value];
135 }
136 - (id)initWithCoder:(NSCoder *)_coder {
137   if ((self = [super init])) {
138     self->value = [[_coder decodeObject] retain];
139   }
140   return self;
141 }
142
143 /* NSCopying */
144
145 - (id)copyWithZone:(NSZone *)_zone {
146   return [self retain];
147 }
148
149 /* description */
150
151 - (NSString *)description {
152   NSMutableString *str;
153
154   str = [NSMutableString stringWithCapacity:64];
155   [str appendFormat:@"<0x%08X[%@]:", self, NSStringFromClass([self class])];
156   [str appendString:@" value="];
157   if ([self->value isKindOfClass:[NSString class]]) {
158     NSString *v = self->value;
159     
160     [str appendString:@"\""];
161     if ([self->value length] > 10) {
162       v = [v substringToIndex:9];
163       v = [v stringByApplyingCEscaping];
164       [str appendString:v];
165       [str appendFormat:@"...[len=%i]", [self->value length]];
166     }
167     else {
168       v = [v stringByApplyingCEscaping];
169       [str appendString:v];
170     }
171     [str appendString:@"\""];
172   }
173   else {
174     [str appendString:[self->value description]];
175     [str appendFormat:@"(%@)", NSStringFromClass([self->value class])];
176   }
177   [str appendString:@">"];
178
179   return str;
180 }
181
182 @end /* WOValueAssociation */
183
184 @implementation _WOBoolValueAssociation
185
186 static _WOBoolValueAssociation *yesAssoc = nil;
187 static _WOBoolValueAssociation *noAssoc  = nil;
188 static NSNumber *yesNum = nil;
189 static NSNumber *noNum  = nil;
190
191 + (void)initialize {
192   if (yesNum == nil) yesNum = [[NSNumber numberWithBool:YES] retain];
193   if (noNum  == nil) noNum  = [[NSNumber numberWithBool:NO] retain];
194 }
195
196 + (WOAssociation *)associationWithBool:(BOOL)_value {
197   if (_value) {
198     if (yesAssoc == nil) {
199       yesAssoc = [[_WOBoolValueAssociation alloc] init];
200       yesAssoc->value = YES;
201     }
202     return yesAssoc;
203   }
204   else {
205     if (noAssoc == nil) {
206       noAssoc = [[_WOBoolValueAssociation alloc] init];
207       noAssoc->value = NO;
208     }
209     return noAssoc;
210   }
211 }
212 + (WOAssociation *)associationWithValue:(id)_value {
213   return [self associationWithBool:[_value boolValue]];
214 }
215
216 /* value */
217
218 - (void)setValue:(id)_value inComponent:(WOComponent *)_component {
219   // not settable
220   [NSException raise:@"AssociationException"
221                format:@"association value is not settable !"];
222 }
223 - (id)valueInComponent:(WOComponent *)_component {
224   return self->value ? yesNum : noNum;
225 }
226
227 - (BOOL)isValueConstant {
228   return YES;
229 }
230 - (BOOL)isValueSettable {
231   return NO;
232 }
233
234 /* special values */
235
236 - (unsigned int)unsignedIntValueInComponent:(WOComponent *)_component {
237   return self->value ? 1 : 0;
238 }
239 - (int)intValueInComponent:(WOComponent *)_component {
240   return self->value ? 1 : 0;
241 }
242 - (BOOL)boolValueInComponent:(WOComponent *)_component {
243   return self->value;
244 }
245 - (NSString *)stringValueInComponent:(WOComponent *)_component {
246   return self->value ? @"YES" : @"NO";
247 }
248
249 /* NSCopying */
250
251 - (id)copyWithZone:(NSZone *)_zone {
252   return [self retain];
253 }
254
255 /* description */
256
257 - (NSString *)description {
258   return [NSString stringWithFormat:@"<%@[0x%08X]: %s",
259                      NSStringFromClass([self class]), self,
260                      self->value ? "YES" : "NO"];
261 }
262
263 @end /* _WOBoolValueAssociation */