#include "WOComponentFault.h"
#include "common.h"
#include <NGExtensions/NGBundleManager.h>
-#include <EOControl/EOControl.h>
+#import <EOControl/EOControl.h>
+#ifdef MULLE_EO_CONTROL
+#import <EOControl/EOKeyValueUnarchiver.h>
+#endif
#include <NGExtensions/NSString+Ext.h>
@interface WOContext(ComponentStackCount)
static BOOL debugOn = NO;
static BOOL debugComponentAwake = NO;
static BOOL debugTemplates = NO;
+static BOOL debugTakeValues = NO;
static BOOL abortOnAwakeComponentInCtxDealloc = NO;
static BOOL abortOnMissingCtx = NO;
static BOOL wakeupPageOnCreation = NO;
ud = [NSUserDefaults standardUserDefaults];
lm = [NGLoggerManager defaultLoggerManager];
-
+
WOComponentClass = [WOComponent class];
NSDateClass = [NSDate class];
perfLogger = [lm loggerForDefaultKey:@"WOProfileElements"];
debugOn = [WOApplication isDebuggingEnabled];
debugComponentAwake = [ud boolForKey:@"WODebugComponentAwake"];
+
+ if ((debugTakeValues = [ud boolForKey:@"WODebugTakeValues"]))
+ NSLog(@"WOComponent: WODebugTakeValues on.");
+
abortOnAwakeComponentInCtxDealloc =
[ud boolForKey:@"WOCoreOnAwakeComponentInCtxDealloc"];
}
if (self->componentFlags.isAwake) {
[self warnWithFormat:
- @"session will dealloc, but component 0x%08X is awake (ctx=%@) !",
+ @"session will dealloc, but component 0x%p is awake (ctx=%@) !",
self, self->context];
[self _sleepWithContext:self->context];
}
#endif
if (debugComponentAwake)
- [self debugWithFormat:@"0x%08X ensureAwakeInContext:0x%08X", self, _ctx];
+ [self debugWithFormat:@"0x%p ensureAwakeInContext:0x%p", self, _ctx];
/* sanity check */
if (self->componentFlags.isAwake) {
if (self->context == _ctx) {
if (debugComponentAwake)
- [self debugWithFormat:@"0x%08X already awake:0x%08X", self, _ctx];
+ [self debugWithFormat:@"0x%p already awake:0x%p", self, _ctx];
return;
}
}
}
- (void)_sleepWithContext:(WOContext *)_ctx {
if (debugComponentAwake)
- [self debugWithFormat:@"0x%08X _sleepWithContext:0x%08X", self, _ctx];
+ [self debugWithFormat:@"0x%p _sleepWithContext:0x%p", self, _ctx];
if (_ctx != self->context) {
if ((self->context != nil) && (_ctx != nil)) {
/* component is active in different context ... */
[self warnWithFormat:
- @"sleep context mismatch (own=0x%08X vs given=0x%08X)",
+ @"sleep context mismatch (own=0x%p vs given=0x%p)",
self->context, _ctx];
return;
}
return self->wocName;
}
- (NSString *)frameworkName {
- return [[NGBundle bundleForClass:[self class]] bundleName];
+ NSBundle *cbundle;
+
+ cbundle = [NGBundle bundleForClass:[self class]];
+ if (cbundle == [NSBundle mainBundle])
+ return nil;
+
+ return [cbundle bundleName];
}
- (NSString *)path {
NSArray *languages = nil;
}
- (id)existingSession {
- if (self->session)
+ if (self->session != nil)
return self->session;
if ([[self context] hasSession])
self->context = _ctx;
}
- (WOContext *)context {
- if (self->context)
+ if (self->context != nil)
return self->context;
[self debugWithFormat:
- @"missing context in component 0x%08X (component%s)",
+ @"missing context in component 0x%p (component%s)",
self,
self->componentFlags.isAwake ? " is awake" : " is not awake"];
if (abortOnMissingCtx) {
[self errorWithFormat:@"aborting, because ctx is missing !"];
abort();
}
-
+
if (self->application == nil)
self->application = [WOApplication application];
[self _setContext:[self->application context]];
}
- (NSString *)pathForResourceNamed:(NSString *)_name ofType:(NSString *)_ext {
- NSFileManager *fm = [NSFileManager defaultManager];
- NSEnumerator *languages = nil;
- NSString *language = nil;
+ NSFileManager *fm;
+ NSEnumerator *languages;
+ NSString *language;
BOOL isDirectory = NO;
- NSString *cpath = [self path];
+ NSString *cpath;
if (_ext) _name = [_name stringByAppendingPathExtension:_ext];
- if (cpath == nil) {
+ if ((cpath = [self path]) == nil) {
[self warnWithFormat:@"no path set in component %@", [self name]];
return nil;
}
+
+ fm = [NSFileManager defaultManager];
if (![fm fileExistsAtPath:cpath isDirectory:&isDirectory]) {
[self warnWithFormat:@"component directory %@ does not exist !", cpath];
return nil;
[self warnWithFormat:@"component path %@ is not a directory !", cpath];
return nil;
}
+
+ /* check in language projects */
- // check in language projects
-
- languages = [[(WOSession *)[self session] languages] objectEnumerator];
- while ((language = [languages nextObject])) {
- language = [[cpath stringByAppendingPathComponent:
- [language stringByAppendingPathExtension:@"lproj"]]
- stringByAppendingPathExtension:_name];
+ languages = [self hasSession]
+ ? [[(WOSession *)[self session] languages] objectEnumerator]
+ : [[[[self context] request] browserLanguages] objectEnumerator];
+
+ while ((language = [languages nextObject]) != nil) {
+ language = [language stringByAppendingPathExtension:@"lproj"];
+ language = [cpath stringByAppendingPathComponent:language];
+ language = [language stringByAppendingPathExtension:_name];
if ([fm fileExistsAtPath:language])
return language;
}
-
- // check in component
+
+ /* check in component */
cpath = [cpath stringByAppendingPathComponent:_name];
if ([fm fileExistsAtPath:cpath])
return cpath;
/* template */
-- (WOElement *)templateWithHTMLString:(NSString *)_html
++ (WOElement *)templateWithHTMLString:(NSString *)_html
declarationString:(NSString *)_wod
languages:(NSArray *)_languages
{
declarationString:(NSString *)_wod
{
IS_DEPRECATED;
- return [self templateWithHTMLString:_html
- declarationString:_wod
- languages:[(WOSession *)[self session] languages]];
+ return [[self class] templateWithHTMLString:_html
+ declarationString:_wod
+ languages:[(WOSession *)[self session] languages]];
}
- (WOElement *)templateWithName:(NSString *)_name {
}
- (BOOL)synchronizesVariablesWithBindings {
- return YES;
+ return [self isStateless] ? NO : YES;
}
- (void)setValue:(id)_value forBinding:(NSString *)_name {
/* OWResponder */
-- (BOOL)shouldTakeValuesFromRequest:(WORequest *)_rq inContext:(WOContext*)_c{
+- (BOOL)shouldTakeValuesFromRequest:(WORequest *)_rq inContext:(WOContext*)_c {
+ if (debugTakeValues)
+ [self debugWithFormat:@"%s: default says no.", __PRETTY_FUNCTION__];
return NO;
}
- (void)takeValuesFromRequest:(WORequest *)_req inContext:(WOContext *)_ctx {
WOElement *template = nil;
+ if (debugTakeValues)
+ [self debugWithFormat:@"take values from rq 0x%p", _req];
+
NSAssert1(self->componentFlags.isAwake,
@"component %@ is not awake !", self);
[self _setContext:_ctx];
template = [self _woComponentTemplate];
- if (template == nil)
+ if (template == nil) {
+ if (debugTakeValues)
+ [self debugWithFormat:@"cannot take values, component has no template!"];
return;
-
+ }
+
if (template->takeValues) {
template->takeValues(template,
@selector(takeValuesFromRequest:inContext:),
#if DEBUG && 0
[self debugWithFormat:@"KVC: accessed the component variable %@", _key];
#endif
- if ((value = [self objectForKey:_key]))
+ if ((value = [self objectForKey:_key]) != nil)
return value;
return nil;
- (void)setValue:(id)_value forUndefinedKey:(NSString *)_key {
// Note: this is not used on libFoundation, insufficient KVC implementation
+
+#if DEBUG && 0
+ [self logWithFormat:@"KVC: set the component variable %@: %@",_key,_value];
+#endif
if (_value == nil) {
#if 0
@"storing <nil> value in component variable %@", _key];
#endif
- if ([self->wocVariables objectForKey:_key])
+ if ([self->wocVariables objectForKey:_key] != nil)
[self setObject:nil forKey:_key];
return;
}
}
#endif
-
[self setObject:_value forKey:_key];
}
+
- (id)valueForUndefinedKey:(NSString *)_key {
// Note: this is not used on libFoundation, insufficient KVC implementation
#if DEBUG && 0
[self debugWithFormat:@"KVC: accessed the component variable %@", _key];
#endif
+
return [self objectForKey:_key];
}
- (id)unarchiver:(EOKeyValueUnarchiver *)_archiver
objectForReference:(id)_keyPath
{
+ /*
+ This is used when a .woo file is unarchived. Eg datasources contain
+ bindings in the archive:
+
+ editingContext = session.defaultEditingContext;
+
+ The binding will evaluate against the component during loading.
+ */
return [self valueForKeyPath:_keyPath];
}
id tmp;
str = [NSMutableString stringWithCapacity:128];
- [str appendFormat:@"<0x%08X[%@]: name=%@", self,
+ [str appendFormat:@"<0x%p[%@]: name=%@", self,
NSStringFromClass([self class]), [self name]];
if (self->parentComponent)
[str appendFormat:@" #subs=%i", [self->subcomponents count]];
if (self->componentFlags.isAwake)
- [str appendFormat:@" awake=0x%08X", self->context];
+ [str appendFormat:@" awake=0x%p", self->context];
else if (self->context == nil)
[str appendString:@" no-ctx"];
return str;
}
-@end /* WOComponent */
-
-@implementation WOComponent(Statistics)
+/* Statistics */
- (NSString *)descriptionForResponse:(WOResponse *)_response
inContext:(WOContext *)_context
return [self name];
}
-@end /* WOComponent(Statistics) */
-
-@implementation WOComponent(AdvancedBindingAccessors)
+/* AdvancedBindingAccessors */
- (void)setUnsignedIntValue:(unsigned)_value forBinding:(NSString *)_name {
[self setValue:[NSNumber numberWithUnsignedInt:_value] forBinding:_name];
}
#endif
-@end /* WOComponent(AdvancedBindingAccessors) */
+@end /* WOComponent */