]> err.no Git - sope/blobdiff - sope-appserver/NGObjWeb/WOComponent.m
changed #includes into #imports - does compile against MulleEOF out of the box now
[sope] / sope-appserver / NGObjWeb / WOComponent.m
index 09ab7fd2efb19ae3412ba5eb05b68114480bb59e..7145ed0f9bbb3fc387623f5445002c5b3db7921e 100644 (file)
 #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)
@@ -59,6 +62,7 @@ static NGLogger *perfLogger                    = nil;
 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;
@@ -81,12 +85,16 @@ 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"];
 }
@@ -135,7 +143,7 @@ static BOOL  wakeupPageOnCreation              = NO;
 - (id)initWithContext:(WOContext *)_ctx {
   [self _setContext:_ctx];
   if ((self = [self init])) {
-    if (self->context)
+    if (self->context != nil)
       [self ensureAwakeInContext:self->context];
     else {
       [self warnWithFormat:
@@ -268,7 +276,19 @@ static inline id _getExtraVar(WOComponent *self, NSString *_key) {
   if (debugComponentAwake) 
     [self debugWithFormat:@"0x%08X ensureAwakeInContext:0x%08X", self, _ctx];
   
-  if (self->context == nil)     [self _setContext:_ctx];
+  /* sanity check */
+
+  if (self->componentFlags.isAwake) {
+    if (self->context == _ctx) {
+      if (debugComponentAwake) 
+       [self debugWithFormat:@"0x%08X already awake:0x%08X", self, _ctx];
+      return;
+    }
+  }
+  
+  /* setup globals */
+  
+  if (self->context     == nil) [self _setContext:_ctx];
   if (self->application == nil) self->application = [_ctx application];
   
   if ((self->session == nil) && [_ctx hasSession])
@@ -283,7 +303,7 @@ static inline id _getExtraVar(WOComponent *self, NSString *_key) {
     WOComponent  *child;
     
     children = [self->subcomponents objectEnumerator];
-    while ((child = [children nextObject]))
+    while ((child = [children nextObject]) != nil)
       [child _awakeWithContext:_ctx];
   }
   
@@ -338,15 +358,19 @@ static inline id _getExtraVar(WOComponent *self, NSString *_key) {
   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;
   
 #if 0 // the component might not yet be awake !
-  languages = [self hasSession]
-    ? [[self session] languages]
-    : [[[self context] request] browserLanguages];
+  languages = [[self context] resourceLookupLanguages];
 #endif
   
   return [[self resourceManager]
@@ -373,14 +397,14 @@ static inline id _getExtraVar(WOComponent *self, NSString *_key) {
   return [@"/" stringByAppendingString:[self name]];
 }
 
-- (WOApplication *)application {
+- (id)application {
   if (self->application == nil)
     return (self->application = [WOApplication application]);
   return self->application;
 }
 
 - (id)existingSession {
-  if (self->session)
+  if (self->session != nil)
     return self->session;
   
   if ([[self context] hasSession])
@@ -388,7 +412,7 @@ static inline id _getExtraVar(WOComponent *self, NSString *_key) {
 
   return nil;
 }
-- (WOSession *)session {
+- (id)session {
   if (self->session == nil) {
     if ((self->session = [[self context] session]) == nil) {
       [self debugWithFormat:@"could not get session object from context %@",
@@ -433,23 +457,20 @@ static inline id _getExtraVar(WOComponent *self, NSString *_key) {
 }
 
 - (void)setCachingEnabled:(BOOL)_flag {
-  self->componentFlags.reloadTemplates = _flag ? NO : YES;
+  self->componentFlags.reloadTemplates = _flag ? 0 : 1;
 }
 - (BOOL)isCachingEnabled {
-  return (self->componentFlags.reloadTemplates == NO) ? YES : NO;
+  return (!self->componentFlags.reloadTemplates) ? YES : NO;
 }
 
-- (WOComponent *)pageWithName:(NSString *)_name {
-  NSArray *languages = nil;
+- (id)pageWithName:(NSString *)_name {
+  NSArray           *languages;
   WOResourceManager *rm;
   WOComponent       *component;
   
-  languages = [self hasSession]
-    ? [(WOSession *)[self session] languages]
-    : [[[self context] request] browserLanguages];
-  
-  rm = [self resourceManager];
-  
+  languages = [[self context] resourceLookupLanguages];
+  rm        = [self resourceManager];
+
   /* 
      Note: this API is somewhat broken since the component expects the
            -initWithContext: message for initialization yet we pass no
@@ -476,9 +497,7 @@ static inline id _getExtraVar(WOComponent *self, NSString *_key) {
   NSArray *langs;
   IS_DEPRECATED;
   
-  langs = [self hasSession]
-    ? [(WOSession *)[self session] languages]
-    : [[[self context] request] browserLanguages];
+  langs = [[self context] resourceLookupLanguages];
   
   return [[[self application]
                  resourceManager]
@@ -515,7 +534,7 @@ static inline id _getExtraVar(WOComponent *self, NSString *_key) {
 - (void)setParent:(WOComponent *)_parent {
   self->parentComponent = _parent;
 }
-- (WOComponent *)parent {
+- (id)parent {
   return self->parentComponent;
 }
 
@@ -591,18 +610,20 @@ static inline id _getExtraVar(WOComponent *self, NSString *_key) {
 }
 
 - (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;
@@ -611,20 +632,23 @@ static inline id _getExtraVar(WOComponent *self, NSString *_key) {
     [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;
@@ -634,7 +658,7 @@ static inline id _getExtraVar(WOComponent *self, NSString *_key) {
 
 /* template */
 
-- (WOElement *)templateWithHTMLString:(NSString *)_html
++ (WOElement *)templateWithHTMLString:(NSString *)_html
   declarationString:(NSString *)_wod
   languages:(NSArray *)_languages
 {
@@ -644,9 +668,9 @@ static inline id _getExtraVar(WOComponent *self, NSString *_key) {
   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 {
@@ -660,11 +684,9 @@ static inline id _getExtraVar(WOComponent *self, NSString *_key) {
     return nil;
   }
   
-  languages = [self hasSession]
-    ? [(WOSession *)[self  session] languages]
-    : [[[self context] request] browserLanguages];
-  
-  tmpl = [resourceManager templateWithName:_name languages:languages];
+  languages = [[self context] resourceLookupLanguages];
+  tmpl      = [resourceManager templateWithName:_name languages:languages];
+
   if (debugTemplates) [self debugWithFormat:@"found template: %@", tmpl];
   return tmpl;
 }
@@ -680,7 +702,8 @@ static inline id _getExtraVar(WOComponent *self, NSString *_key) {
 - (WOElement *)_woComponentTemplate {
   WOElement *element;
   
-  if ((element = _getExtraVar(self, @"__wotemplate")))
+  // TODO: move to ivar?
+  if ((element = _getExtraVar(self, @"__wotemplate")) != nil)
     return element;
   
   return [self templateWithName:[self name]];
@@ -711,7 +734,7 @@ static inline id _getExtraVar(WOComponent *self, NSString *_key) {
 }
 
 - (BOOL)synchronizesVariablesWithBindings {
-  return YES;
+  return [self isStateless] ? NO : YES;
 }
 
 - (void)setValue:(id)_value forBinding:(NSString *)_name {
@@ -826,22 +849,30 @@ static inline id _getExtraVar(WOComponent *self, NSString *_key) {
 
 /* 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%08X", _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:),
@@ -1057,7 +1088,7 @@ static inline id _getExtraVar(WOComponent *self, NSString *_key) {
 #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;
@@ -1067,6 +1098,10 @@ static inline id _getExtraVar(WOComponent *self, NSString *_key) {
 
 - (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
@@ -1074,7 +1109,7 @@ static inline id _getExtraVar(WOComponent *self, NSString *_key) {
            @"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;
@@ -1089,14 +1124,15 @@ static inline id _getExtraVar(WOComponent *self, NSString *_key) {
     }
   }
 #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];
 }
 
@@ -1148,6 +1184,14 @@ static inline id _getExtraVar(WOComponent *self, NSString *_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];
 }
 
@@ -1185,9 +1229,7 @@ static inline id _getExtraVar(WOComponent *self, NSString *_key) {
   return str;
 }
 
-@end /* WOComponent */
-
-@implementation WOComponent(Statistics)
+/* Statistics */
 
 - (NSString *)descriptionForResponse:(WOResponse *)_response
   inContext:(WOContext *)_context
@@ -1195,9 +1237,7 @@ static inline id _getExtraVar(WOComponent *self, NSString *_key) {
   return [self name];
 }
 
-@end /* WOComponent(Statistics) */
-
-@implementation WOComponent(AdvancedBindingAccessors)
+/* AdvancedBindingAccessors */
 
 - (void)setUnsignedIntValue:(unsigned)_value forBinding:(NSString *)_name {
   [self setValue:[NSNumber numberWithUnsignedInt:_value] forBinding:_name];
@@ -1227,4 +1267,4 @@ static inline id _getExtraVar(WOComponent *self, NSString *_key) {
 }
 #endif
 
-@end /* WOComponent(AdvancedBindingAccessors) */
+@end /* WOComponent */