]> err.no Git - sope/blobdiff - sope-appserver/NGObjWeb/WOComponent.m
bumped Xcode projects to version 4.7. Added a new Xcode project for the STXSaxDriver.
[sope] / sope-appserver / NGObjWeb / WOComponent.m
index efe54cc3b24a3b0c5a83a2805710e7062ca06e5d..4b82493f045637ac9651382a4f493a82e5c0dc68 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"];
 }
@@ -196,7 +204,7 @@ static inline id _getExtraVar(WOComponent *self, NSString *_key) {
   
   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];
   }
@@ -266,14 +274,14 @@ static inline id _getExtraVar(WOComponent *self, NSString *_key) {
 #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;
     }
   }
@@ -310,13 +318,13 @@ static inline id _getExtraVar(WOComponent *self, NSString *_key) {
 }
 - (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;
     }
@@ -350,7 +358,13 @@ 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;
@@ -390,7 +404,7 @@ static inline id _getExtraVar(WOComponent *self, NSString *_key) {
 }
 
 - (id)existingSession {
-  if (self->session)
+  if (self->session != nil)
     return self->session;
   
   if ([[self context] hasSession])
@@ -416,18 +430,18 @@ static inline id _getExtraVar(WOComponent *self, NSString *_key) {
   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]];
@@ -596,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;
@@ -616,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;
@@ -639,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
 {
@@ -649,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 {
@@ -715,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 {
@@ -830,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%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:),
@@ -1061,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;
@@ -1071,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
@@ -1078,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;
@@ -1093,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];
 }
 
@@ -1152,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];
 }
 
@@ -1169,7 +1209,7 @@ static inline id _getExtraVar(WOComponent *self, NSString *_key) {
   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)
@@ -1178,7 +1218,7 @@ static inline id _getExtraVar(WOComponent *self, NSString *_key) {
     [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"];
   
@@ -1189,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
@@ -1199,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];
@@ -1231,4 +1267,4 @@ static inline id _getExtraVar(WOComponent *self, NSString *_key) {
 }
 #endif
 
-@end /* WOComponent(AdvancedBindingAccessors) */
+@end /* WOComponent */