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