]> err.no Git - sope/blob - sope-appserver/NGObjWeb/Associations/WOKeyPathAssociationSystemKVC.m
improved SOPE security exceptions
[sope] / sope-appserver / NGObjWeb / Associations / WOKeyPathAssociationSystemKVC.m
1 /*
2   Copyright (C) 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 "WOKeyPathAssociation.h"
24 #include <NGObjWeb/WOComponent.h>
25 #include "NSObject+WO.h"
26 #include "common.h"
27
28 /*
29   WOKeyPathAssociationSystemKVC
30   
31   This is an WOKeyPathAssociation subclass which uses the KVC methods
32   provided in the Foundation library. This is much less performant, but
33   much more compatible with WebObjects.
34   
35   This could be further optimized by doing method caching, using shared
36   objects, etc. Yet if you need speed, you should use the default association.
37 */
38
39 @interface WOKeyPathAssociationSystemKVC : WOKeyPathAssociation
40 {
41   NSString *keyPathString;
42   BOOL     hasCaretPrefix;
43 }
44
45 @end
46
47 @implementation WOKeyPathAssociationSystemKVC
48
49 static NSNumber *yesNum = nil;
50 static NSNumber *noNum  = nil;
51
52 + (int)version {
53   return [super version] + 0; /* v2 */
54 }
55 + (void)initialize {
56   if (yesNum == nil) yesNum = [[NSNumber numberWithBool:YES] retain];
57   if (noNum  == nil) noNum  = [[NSNumber numberWithBool:NO]  retain];
58 }
59
60 - (id)initWithKeyPath:(NSString *)_keyPath {
61   if ((self = [super initWithKeyPath:_keyPath])) {
62     self->hasCaretPrefix = 
63       (([_keyPath length] > 1) && [_keyPath hasPrefix:@"^"]) ? YES : NO;
64     
65     if (self->hasCaretPrefix)
66       self->keyPathString = [[_keyPath substringFromIndex:1] copy];
67     else
68       self->keyPathString = [_keyPath copy];
69   }
70   return self;
71 }
72
73 - (void)dealloc {
74   [self->keyPathString release];
75   [super dealloc];
76 }
77
78 /* accessors */
79
80 - (NSString *)keyPath {
81   return self->keyPathString;
82 }
83
84 /* value */
85
86 - (void)setValue:(id)_value inComponent:(WOComponent *)_component {
87   if (self->hasCaretPrefix)
88     [_component setValue:_value forBinding:self->keyPathString];
89   else
90     [_component takeValue:_value forKeyPath:self->keyPathString];
91 }
92 - (id)valueInComponent:(WOComponent *)_component {
93   return (self->hasCaretPrefix)
94     ? [_component valueForBinding:self->keyPathString]
95     : [_component valueForKeyPath:self->keyPathString];
96 }
97
98 - (BOOL)isValueConstant {
99   return NO;
100 }
101 - (BOOL)isValueSettable {
102   return YES;
103 }
104
105 /* special values */
106
107 - (void)setUnsignedIntValue:(unsigned int)_v inComponent:(WOComponent *)_wo {
108   [self setValue:[NSNumber numberWithUnsignedInt:_v] inComponent:_wo];
109 }
110 - (unsigned int)unsignedIntValueInComponent:(WOComponent *)_component {
111   return [[self valueInComponent:_component] unsignedIntValue];
112 }
113
114 - (void)setIntValue:(int)_value inComponent:(WOComponent *)_wo {
115   [self setValue:[NSNumber numberWithInt:_value] inComponent:_wo];
116 }
117 - (int)intValueInComponent:(WOComponent *)_component {
118   return [[self valueInComponent:_component] intValue];
119 }
120
121 - (void)setBoolValue:(BOOL)_value inComponent:(WOComponent *)_wo {
122   [self setValue:(_value ? yesNum : noNum) inComponent:_wo];
123 }
124 - (BOOL)boolValueInComponent:(WOComponent *)_component {
125   /* some optimizations, very likely that same objects are used for YES|NO */
126   id o;
127   
128   if ((o = [self valueInComponent:_component]) == nil)
129     return NO;
130   if (o == yesNum) return YES;
131   if (o == noNum)  return NO;
132   return [o boolValue];
133 }
134
135 - (void)setStringValue:(NSString *)_value inComponent:(WOComponent *)_wo {
136   [self setValue:_value inComponent:_wo];
137 }
138 - (NSString *)stringValueInComponent:(WOComponent *)_component {
139   return [[self valueInComponent:_component] stringValue];
140 }
141
142 @end /* WOKeyPathAssociationSystemKVC */