2 Copyright (C) 2000-2003 SKYRIX Software AG
4 This file is part of OGo
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
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.
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
21 // $Id: WOScriptedComponent.m 1 2004-08-20 10:08:27Z znek $
23 #include "WOScriptedComponent.h"
24 #include <NGObjWeb/WOTemplateBuilder.h>
25 #include <NGScripting/NGScriptLanguage.h>
28 @interface NSObject(misc)
29 - (void)applyStandardClasses;
30 - (BOOL)isScriptFunction;
32 - (id)callScriptFunction:(NSString *)_name withObject:(id)_arg0;
33 - (id)evaluateScript:(NSString *)_script source:(NSString *)_s line:(int)_line;
37 @interface WOComponent(UsedPrivates)
38 - (id)initWithName:(NSString *)_cname
39 template:(WOTemplate *)_template
40 inContext:(WOContext *)_ctx;
43 @interface WOComponentScript(UsedPrivates)
44 - (id)initScriptWithComponent:(id)_comp;
47 @implementation WOScriptedComponent
49 static BOOL logScriptKVC = NO;
50 static BOOL logScriptInit = NO;
51 static BOOL logScriptDealloc = NO;
54 static BOOL didInit = NO;
56 NSUserDefaults *ud = [NSUserDefaults standardUserDefaults];
58 logScriptKVC = [ud boolForKey:@"WOLogScriptKVC"];
59 logScriptInit = [ud boolForKey:@"WOLogScriptInit"];
60 logScriptDealloc = [ud boolForKey:@"WOLogScriptDealloc"];
64 - (id)initWithName:(NSString *)_cname
65 template:(WOTemplate *)_template
66 inContext:(WOContext *)_ctx
68 if ((self = [super initWithName:_cname template:_template inContext:_ctx])) {
69 self->script = [[_template componentScript] retain];
72 [[NGScriptLanguage languageWithName:[self->script language]] retain];
73 if (self->language == nil) {
75 @"did not find engine for script language %@",
76 [self->script language]];
81 if ((self->shadow = [self->language createShadowForMaster:self]) == nil) {
83 @"could not create shadow for component in language %@",
89 if ([self->shadow respondsToSelector:@selector(applyStandardClasses)])
90 [(id)self->shadow applyStandardClasses];
92 [self->script initScriptWithComponent:self];
95 [self logWithFormat:@"created scripted component: %@", self];
101 if (logScriptDealloc)
102 [self logWithFormat:@"will dealloc scripted component: %@", self];
104 [self->shadow invalidateShadow]; /* ensure shadow is dead ;-) */
105 RELEASE(self->shadow);
106 RELEASE(self->language);
107 RELEASE(self->script);
108 RELEASE(self->template);
114 - (void)setTemplate:(id)_template {
115 ASSIGN(self->template, _template);
117 - (WOElement *)_woComponentTemplate {
118 return self->template;
121 - (BOOL)isScriptedComponent {
127 - (id)evaluateScript:(NSString *)_script language:(NSString *)_lang
128 source:(NSString *)_src line:(unsigned)_line
130 return [self->shadow evaluateScript:_script source:_src line:_line];
133 /* notification mapping */
138 if ([self->shadow hasFunctionNamed:@"awake"])
139 [self->shadow callScriptFunction:@"awake"];
142 if ([self->shadow hasFunctionNamed:@"sleep"])
143 [self->shadow callScriptFunction:@"sleep"];
145 //[self debugWithFormat:@"vars: %@", [self variableDictionary]];
149 /* script properties */
151 - (BOOL)takeValue:(id)_value forJSPropertyNamed:(NSString *)_key {
152 NSAssert1(self->shadow, @"missing shadow for component %@", self);
153 [self->shadow setObject:_value forKey:_key];
156 - (id)valueForJSPropertyNamed:(NSString *)_key {
157 [self debugWithFormat:@"value for prop %@", _key];
158 NSAssert1(self->shadow, @"missing shadow for component %@", self);
159 return [self->shadow objectForKey:_key];
162 /* extra variables */
164 - (void)setObject:(id)_obj forKey:(NSString *)_key {
165 //[self debugWithFormat:@"setObject:%@ forKey:%@", _obj, _key];
166 NSAssert1(self->shadow, @"missing shadow for component %@", self);
167 [self->shadow setObject:_obj forKey:_key];
169 - (id)objectForKey:(NSString *)_key {
170 NSAssert1(self->shadow, @"missing shadow for component %@", self);
171 return [self->shadow objectForKey:_key];
174 /* key-value coding */
176 - (void)takeValue:(id)_value forKey:(NSString *)_key {
182 len = [_key cStringLength];
183 buf = malloc(len + 4);
184 [_key getCString:&(buf[3])];
185 buf[0] = 's'; buf[1] = 'e'; buf[2] = 't';
187 if (len > 0) buf[3] = toupper(buf[3]);
188 funcName = [NSString stringWithCString:buf length:(len + 3)];
191 if ((func = [self->shadow objectForKey:funcName])) {
192 if ([func isScriptFunction]) {
196 [self logWithFormat:@"KVC: for key %@ call %@(%@)",
197 _key, funcName, _value];
200 result = [self->shadow callScriptFunction:funcName withObject:_value];
204 @"KVC: object stored at '%@' is not a function, "
205 @"could not set value for key %@ !",
211 [self logWithFormat:@"KVC: assign %@=%@ (no func '%@')",
212 _key, _value, funcName];
215 [self->shadow setObject:_value forKey:_key];
219 - (id)valueForKey:(NSString *)_key {
222 //[self logWithFormat:@"script: valueForKey:%@", _key];
224 if ((obj = [self->shadow objectForKey:_key])) {
225 if ([obj isScriptFunction]) {
227 [self logWithFormat:@"KVC: for key %@ call %@",
230 obj = [self->shadow callScriptFunction:_key];
234 [self logWithFormat:@"KVC: valueForKey(%@): %@",
242 [self logWithFormat:@"KVC: get value for key %@ from WOComponent",
245 return [super valueForKey:_key];
251 - (NSString *)loggingPrefix {
252 return [NSString stringWithFormat:@"script<%@>[0x%08X]", [self name], self];
255 @end /* WOScriptedComponent */
257 @implementation WOScriptedComponent(JSSupport)
259 - (id)_jsfunc_FileManager:(NSArray *)_args {
260 return [NSFileManager defaultManager];
263 @end /* WOScriptedComponent(JSSupport) */
265 @implementation NSObject(ScriptFunc)
267 - (BOOL)isScriptFunction {
271 @end /* NSObject(ScriptFunc) */