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 "WOScriptedComponent.h"
23 #include <NGObjWeb/WOTemplateBuilder.h>
24 #include <NGScripting/NGScriptLanguage.h>
27 @interface NSObject(misc)
28 - (void)applyStandardClasses;
29 - (BOOL)isScriptFunction;
31 - (id)callScriptFunction:(NSString *)_name withObject:(id)_arg0;
32 - (id)evaluateScript:(NSString *)_script source:(NSString *)_s line:(int)_line;
36 @interface WOComponent(UsedPrivates)
37 - (id)initWithName:(NSString *)_cname
38 template:(WOTemplate *)_template
39 inContext:(WOContext *)_ctx;
42 @interface WOComponentScript(UsedPrivates)
43 - (id)initScriptWithComponent:(id)_comp;
46 @implementation WOScriptedComponent
48 static BOOL logScriptKVC = NO;
49 static BOOL logScriptInit = NO;
50 static BOOL logScriptDealloc = NO;
53 static BOOL didInit = NO;
55 NSUserDefaults *ud = [NSUserDefaults standardUserDefaults];
57 logScriptKVC = [ud boolForKey:@"WOLogScriptKVC"];
58 logScriptInit = [ud boolForKey:@"WOLogScriptInit"];
59 logScriptDealloc = [ud boolForKey:@"WOLogScriptDealloc"];
63 - (id)initWithName:(NSString *)_cname
64 template:(WOTemplate *)_template
65 inContext:(WOContext *)_ctx
67 if ((self = [super initWithName:_cname template:_template inContext:_ctx])) {
68 self->script = [[_template componentScript] retain];
71 [[NGScriptLanguage languageWithName:[self->script language]] retain];
72 if (self->language == nil) {
74 @"did not find engine for script language %@",
75 [self->script language]];
80 if ((self->shadow = [self->language createShadowForMaster:self]) == nil) {
82 @"could not create shadow for component in language %@",
88 if ([self->shadow respondsToSelector:@selector(applyStandardClasses)])
89 [(id)self->shadow applyStandardClasses];
91 [self->script initScriptWithComponent:self];
94 [self logWithFormat:@"created scripted component: %@", self];
100 if (logScriptDealloc)
101 [self logWithFormat:@"will dealloc scripted component: %@", self];
103 [self->shadow invalidateShadow]; /* ensure shadow is dead ;-) */
104 RELEASE(self->shadow);
105 RELEASE(self->language);
106 RELEASE(self->script);
107 RELEASE(self->template);
113 - (void)setTemplate:(id)_template {
114 ASSIGN(self->template, _template);
116 - (WOElement *)_woComponentTemplate {
117 return self->template;
120 - (BOOL)isScriptedComponent {
126 - (id)evaluateScript:(NSString *)_script language:(NSString *)_lang
127 source:(NSString *)_src line:(unsigned)_line
129 return [self->shadow evaluateScript:_script source:_src line:_line];
132 /* notification mapping */
137 if ([self->shadow hasFunctionNamed:@"awake"])
138 [self->shadow callScriptFunction:@"awake"];
141 if ([self->shadow hasFunctionNamed:@"sleep"])
142 [self->shadow callScriptFunction:@"sleep"];
144 //[self debugWithFormat:@"vars: %@", [self variableDictionary]];
148 /* script properties */
150 - (BOOL)takeValue:(id)_value forJSPropertyNamed:(NSString *)_key {
151 NSAssert1(self->shadow, @"missing shadow for component %@", self);
152 [self->shadow setObject:_value forKey:_key];
155 - (id)valueForJSPropertyNamed:(NSString *)_key {
156 [self debugWithFormat:@"value for prop %@", _key];
157 NSAssert1(self->shadow, @"missing shadow for component %@", self);
158 return [self->shadow objectForKey:_key];
161 /* extra variables */
163 - (void)setObject:(id)_obj forKey:(NSString *)_key {
164 //[self debugWithFormat:@"setObject:%@ forKey:%@", _obj, _key];
165 NSAssert1(self->shadow, @"missing shadow for component %@", self);
166 [self->shadow setObject:_obj forKey:_key];
168 - (id)objectForKey:(NSString *)_key {
169 NSAssert1(self->shadow, @"missing shadow for component %@", self);
170 return [self->shadow objectForKey:_key];
173 /* key-value coding */
175 - (void)takeValue:(id)_value forKey:(NSString *)_key {
181 len = [_key cStringLength];
182 buf = malloc(len + 4);
183 [_key getCString:&(buf[3])];
184 buf[0] = 's'; buf[1] = 'e'; buf[2] = 't';
186 if (len > 0) buf[3] = toupper(buf[3]);
187 funcName = [NSString stringWithCString:buf length:(len + 3)];
190 if ((func = [self->shadow objectForKey:funcName])) {
191 if ([func isScriptFunction]) {
195 [self logWithFormat:@"KVC: for key %@ call %@(%@)",
196 _key, funcName, _value];
199 result = [self->shadow callScriptFunction:funcName withObject:_value];
203 @"KVC: object stored at '%@' is not a function, "
204 @"could not set value for key %@ !",
210 [self logWithFormat:@"KVC: assign %@=%@ (no func '%@')",
211 _key, _value, funcName];
214 [self->shadow setObject:_value forKey:_key];
218 - (id)valueForKey:(NSString *)_key {
221 //[self logWithFormat:@"script: valueForKey:%@", _key];
223 if ((obj = [self->shadow objectForKey:_key])) {
224 if ([obj isScriptFunction]) {
226 [self logWithFormat:@"KVC: for key %@ call %@",
229 obj = [self->shadow callScriptFunction:_key];
233 [self logWithFormat:@"KVC: valueForKey(%@): %@",
241 [self logWithFormat:@"KVC: get value for key %@ from WOComponent",
244 return [super valueForKey:_key];
250 - (NSString *)loggingPrefix {
251 return [NSString stringWithFormat:@"script<%@>[0x%08X]", [self name], self];
254 @end /* WOScriptedComponent */
256 @implementation NSObject(ScriptFunc)
258 - (BOOL)isScriptFunction {
262 @end /* NSObject(ScriptFunc) */