]> err.no Git - sope/commitdiff
use logging framework in WOKeyPathAssociation
authorhelge <helge@e4a50df8-12e2-0310-a44c-efbce7f8a7e3>
Sun, 12 Mar 2006 20:33:46 +0000 (20:33 +0000)
committerhelge <helge@e4a50df8-12e2-0310-a44c-efbce7f8a7e3>
Sun, 12 Mar 2006 20:33:46 +0000 (20:33 +0000)
added SoProductLoader class to load SoProduct bundles

git-svn-id: http://svn.opengroupware.org/SOPE/trunk@1223 e4a50df8-12e2-0310-a44c-efbce7f8a7e3

sope-appserver/NGObjWeb/Associations/WOKeyPathAssociation.m
sope-appserver/NGObjWeb/ChangeLog
sope-appserver/NGObjWeb/SoObjects/GNUmakefile
sope-appserver/NGObjWeb/SoObjects/SoProductLoader.h [new file with mode: 0644]
sope-appserver/NGObjWeb/SoObjects/SoProductLoader.m [new file with mode: 0644]
sope-appserver/NGObjWeb/Version
sope-appserver/NGObjWeb/WOComponent.m

index 61d7ad1bea8837f59c84e342ddd2d9a4f66cdbb7..fd06a27e3624a2a5a7d3dde972db8fc4a3ba240e 100644 (file)
@@ -77,6 +77,7 @@ bool _CFDictionaryIsMutable(CFDictionaryRef dict);
   category on NSObject it eliminates the caching scheme used.
 */
 
+// TODO: properly use logging framework for debug messages
 #if DEBUG
 // #define HEAVY_DEBUG 1
 // #define USE_EXCEPTION_HANDLERS 1
@@ -299,14 +300,14 @@ _parseKeyPath(WOKeyPathAssociation *self,NSString *_keyPath)
   return self;
 }
 - (id)init {
-  NSLog(@"keypaths can not be created using 'init' ..");
+  [self errorWithFormat:@"keypaths can not be created using 'init' .."];
   [NSException raise:@"InvalidUseOfMethodException"
                format:@"keypaths can not be created using 'init'"];
   return nil;
 }
 
 - (void)dealloc {
-  if (self->keyPath) {
+  if (self->keyPath != NULL) {
     int cnt;
     
     for (cnt = 0; cnt < self->size; cnt++)
@@ -400,8 +401,15 @@ static inline void _fillInfo(WOKeyPathAssociation *self, id object,
         [[StringClass alloc] initWithCString:(char *)(info->ckey + 1)];
     }
     else {
-      if (object) {
+      if (object != nil) {
         if (object_is_instance(object)) {
+         /*
+           kvcIsPreferredInKeyPath means that for some objects the keys will
+           be probed first. The prominent example is NSDictionary, if you
+           say valueForKey:@"count" you want to resolve to the 'count' key
+           stored in the dictionary, NOT to the -count method of the
+           NSDictionary class.
+         */
           if ([object kvcIsPreferredInKeyPath]) {
             method = class_get_instance_method(clazz, @selector(valueForKey:));
             
@@ -466,7 +474,7 @@ static inline void _fillInfo(WOKeyPathAssociation *self, id object,
     }
 
 #if HEAVY_DEBUG
-    NSLog(@"type is %i, key is '%s'", info->type, info->ckey);
+    [self logWithFormat:@"type is %i, key is '%s'", info->type, info->ckey];
 #endif
   }
 }
@@ -476,7 +484,7 @@ static inline void _fillInfo(WOKeyPathAssociation *self, id object,
   static NSString *kpKey     = @"keyPath";
   static NSString *assocKey  = @"association";
   static NSString *excName   = @"WOKeyPathException";
-  static NSString *excReason = @"couldn't get value for a keypath component";
+  static NSString *excReason = @"could not get value for a keypath component";
   NSException  *e;
   NSDictionary *ui;
   
@@ -507,11 +515,11 @@ static WOReturnValueHolder _getComponentValue(WOKeyPathAssociation *self,
   // execute
   if (info->type == WOKeyType_method) {
 #if HEAVY_DEBUG
-    NSLog(@"get key %s of keyPath %@\n"
+    [self logWithFormat:@"get key %s of keyPath %@\n"
          @"  from: 0x%08X[%@]\n"
          @"  via method (ret %c)", 
          info->ckey, [self keyPath], object, 
-         NSStringFromClass([object class]), info->retType);
+         NSStringFromClass([object class]), info->retType];
 #endif
 #if USE_EXCEPTION_HANDLERS
     NS_DURING {
@@ -519,9 +527,9 @@ static WOReturnValueHolder _getComponentValue(WOKeyPathAssociation *self,
       if ((info->retType == _C_ID) || (info->retType == _C_CLASS)) {
         retValue.object = info->access.method(object, info->extra.sel.get);
 #if HEAVY_DEBUG
-       NSLog(@"  got result 0x%08X[%@]: %@", retValue.object,
+       [self logWithFormat:@"  got result 0x%08X[%@]: %@", retValue.object,
              NSStringFromClass([retValue.object class]),
-             retValue.object);
+             retValue.object];
 #endif
       }
       else {
@@ -566,7 +574,7 @@ static WOReturnValueHolder _getComponentValue(WOKeyPathAssociation *self,
             break;
 
           default:
-            NSLog(@"%@: unsupported type '%c' !", self, info->retType);
+            [self errorWithFormat:@"unsupported type '%c' !", info->retType];
             [NSException raise:@"WORuntimeException"
                          format:
                          @"in WOKeyPathAssociation %@: unsupported type '%c'",
@@ -583,7 +591,8 @@ static WOReturnValueHolder _getComponentValue(WOKeyPathAssociation *self,
   }
   else if (info->type == WOKeyType_kvc) {
 #if HEAVY_DEBUG
-    NSLog(@"get keyPath %@ from %@ via KVC", [self keyPath], object);
+    [self logWithFormat:@"get keyPath %@ from %@ via KVC",
+           [self keyPath], object];
 #endif
 #if 0
     NSLog(@"ckey:      %s", info->ckey);
@@ -600,7 +609,8 @@ static WOReturnValueHolder _getComponentValue(WOKeyPathAssociation *self,
   }
   else if (info->type == WOKeyType_binding) {
 #if HEAVY_DEBUG
-    NSLog(@"get keyPath %@ from %@ via binding", [self keyPath], object);
+    [self logWithFormat:@"get keyPath %@ from %@ via binding", 
+           [self keyPath], object];
 #endif
     
     retValue.object =
@@ -608,8 +618,8 @@ static WOReturnValueHolder _getComponentValue(WOKeyPathAssociation *self,
   }
   else { // unknown || ivar
 #if HEAVY_DEBUG
-    NSLog(@"unknown info type for keyPath %@ from %@ !!",
-          [self keyPath], object);
+    [self logWithFormat:@"unknown info type for keyPath %@ from %@ !!",
+          [self keyPath], object];
 #endif
     retValue.object = nil;
   }
@@ -620,7 +630,7 @@ static WOReturnValueHolder _getComponentValue(WOKeyPathAssociation *self,
 static inline id _objectify(unsigned char _type, WOReturnValueHolder *_value) {
   id result = nil;
 
-  //NSLog(@"shall convert value of type '%c'", _type);
+  //[self logWithFormat:@"shall convert value of type '%c'", _type];
   
   switch (_type) {
     case _C_ID:
@@ -663,14 +673,14 @@ static inline id _objectify(unsigned char _type, WOReturnValueHolder *_value) {
       break;
             
     default:
-      NSLog(@"unsupported type '%c' !", _type);
+      NSLog(@"%s: unsupported type '%c' !", __PRETTY_FUNCTION__, _type);
       [NSException raise:@"WORuntimeException"
                    format:@"in WOKeyPathAssociation: unsupported type '%c'",
                      _type];
       break;
   }
 
-  //NSLog(@"made %@[0x%08X].", NSStringFromClass([result class]), result);
+  // NSLog(@"made %@[0x%08X].", NSStringFromClass([result class]), result);
   
   return result;
 }
@@ -711,7 +721,7 @@ static id _getOneValue(WOKeyPathAssociation *self, id root) {
 
   info     = (WOKeyPathComponent *)self->keyPath;
   retValue = _getComponentValue(self, root, info);
-  
+
   return (info->type == WOKeyType_method)
     ? _objectify(info->retType, &retValue)
     : retValue.object;
@@ -777,23 +787,23 @@ static BOOL _setValue(WOKeyPathAssociation *self, id _value, id root) {
   NSCAssert(info->keyLen < 255, @"keysize to big ..");
 
   _fillInfo(self, object, info);
-  
+
   if (info->type == WOKeyType_method) { // determine set-selector
     SEL setSel = _getSetSel(info->ckey, info->keyLen);
       
     if (![object respondsToSelector:setSel]) {
-#if 0
-      NSLog(@"%@: Could not set value for key '%s', "
+#if 1
+      [self errorWithFormat:@"Could not set value for key '%s', "
             @"object %@ doesn't respond to %@.",
             self, info->ckey, object,
-            setSel ? NSStringFromSelector(setSel) : @"<NULL>");
+            setSel ? NSStringFromSelector(setSel) : @"<NULL>"];
 #endif
       return NO;
     }
     else {
       WOSetMethodType sm;
 
-      if ((sm.method = [object methodForSelector:setSel])) {
+      if ((sm.method = [object methodForSelector:setSel]) != NULL) {
         switch (info->retType) {
           case _C_CLASS:
           case _C_ID:
@@ -848,9 +858,10 @@ static BOOL _setValue(WOKeyPathAssociation *self, id _value, id root) {
             break;
             
           default:
-            NSLog(@"%@: cannot set type '%c' yet (key=%s, method=%@) ..",
-                  self, info->retType, info->ckey,
-                  NSStringFromSelector(setSel));
+            [self errorWithFormat:
+                   @"cannot set type '%c' yet (key=%s, method=%@) ..",
+                    info->retType, info->ckey,
+                    NSStringFromSelector(setSel)];
             [NSException raise:@"WORuntimeException"
                          format:
                            @"in WOKeyPathAssociation %@: "
@@ -862,21 +873,44 @@ static BOOL _setValue(WOKeyPathAssociation *self, id _value, id root) {
         return YES;
       }
       else {
-        NSLog(@"%@: did not find method %@ in object %@",
-              self, NSStringFromSelector(setSel), object);
+        [self logWithFormat:@"did not find method %@ in object %@",
+              NSStringFromSelector(setSel), object];
         return NO;
       }
     }
   }
   else if (info->type == WOKeyType_kvc) { // takeValue:forKey:..
     NSCAssert(info->extra.key, @"no key object set ..");
+
+    /*
+      The following check is necessary because starting with Cocoa Foundation
+      v10.3? mutable and immutable dictionary objects are the same class :-(
+      
+      To make it worse the _CFDictionaryIsMutable is a private function which
+      might vanish ...
+    */
 #if NeXT_Foundation_LIBRARY || COCOA_Foundation_LIBRARY || \
     APPLE_FOUNDATION_LIBRARY
     if([object isKindOfClass:NSCFDictionaryClass] &&
        !_CFDictionaryIsMutable((CFDictionaryRef)object))
         return NO;
 #endif
+
+    /*
+      TODO(hh): Maybe this needs improvement. For non-dictionary like objects
+                (eg WOComponents) this code does the method scanning twice,
+               first we scan the object for method 'key', then the Foundation
+               KVC again scans for the 'key' method prior falling back to
+               handleUnknownKey stuff ...
+    */
+    
+#if GNUSTEP_BASE_LIBRARY && ((GNUSTEP_BASE_MAJOR_VERSION >= 1) && \
+                            (GNUSTEP_BASE_MINOR_VERSION >= 11))
+    // TODO: also do this for OSX 10.4? probably
+    [object setValue:_value forKey:info->extra.key];
+#else
     [object takeValue:_value forKey:info->extra.key];
+#endif
     return YES;
   }
   else if (info->type == WOKeyType_binding) { // setValue:forBinding:
@@ -885,14 +919,15 @@ static BOOL _setValue(WOKeyPathAssociation *self, id _value, id root) {
     return YES;
   }
   else {
-    NSLog(@"%@: Could not set value for key '%s'.", self, info->ckey);
+    // TODO: use errorWithFormat?
+    [self logWithFormat:@"Could not set value for key '%s'.", info->ckey];
     return NO;
   }
 }
 
 - (void)setValue:(id)_value inComponent:(WOComponent *)_component {
   if (debugOn)
-    NSLog(@"%@: set value %@ component %@", self, _value, _component);
+    [self logWithFormat:@"set value %@ component %@", _value, _component];
   
   _setValue(self, _value, _component);
 }
@@ -900,7 +935,7 @@ static BOOL _setValue(WOKeyPathAssociation *self, id _value, id root) {
 #if DEBUG
   volatile id result;
   if (debugOn)
-    NSLog(@"%@: get value in component %@", self, _component);
+    [self logWithFormat:@"get value in component %@", _component];
   
 #if USE_EXCEPTION_HANDLERS
   NS_DURING {
@@ -919,10 +954,12 @@ static BOOL _setValue(WOKeyPathAssociation *self, id _value, id root) {
   }
   NS_ENDHANDLER;
 #endif
+  
   return result;
-#else
+  
+#else /* !DEBUG */
   if (debugOn)
-    NSLog(@"%@: get value in component %@", self, _component);
+    [self logWithFormat:@"get value in component %@", _component];
   
   return (self->size > 1)
     ? _getValue(self, _component)
@@ -945,7 +982,7 @@ static BOOL _setValue(WOKeyPathAssociation *self, id _value, id root) {
   WOKeyPathComponent *info;
   
   if (debugOn)
-    NSLog(@"%@: set uint value %i in component %@", self, _value, _wo);
+    [self logWithFormat:@"set uint value %i in component %@", _value, _wo];
   
   if (self->size > 1) {
     _setValue(self, uintNumObj(_value), _wo);
@@ -970,13 +1007,15 @@ static BOOL _setValue(WOKeyPathAssociation *self, id _value, id root) {
       switch (info->retType) {
           case _C_CHR: {
             if (((int)_value < -126) || ((int)_value > 127))
-              NSLog(@"%@: value (%i) out of range for char !", self, _value);
+              [self errorWithFormat:
+                     @"value (%i) out of range for char!", _value];
             sm.cmethod(_wo, setSel, (char)_value);
             break;
           }
           case _C_UCHR: {
             if ((_value < 0) || (_value > 255))
-              NSLog(@"%@: value (%i) out of range for uchar !", self, _value);
+              [self errorWithFormat:
+                     @"value (%i) out of range for uchar!", _value];
             sm.ucmethod(_wo, setSel, (unsigned char)_value);
             break;
           }
@@ -1016,14 +1055,14 @@ static BOOL _setValue(WOKeyPathAssociation *self, id _value, id root) {
     return;
   }
   
-  NSLog(@"%@: Could not set value for key '%s'.", self, info->ckey);
+  [self errorWithFormat:@"Could not set value for key '%s'.", info->ckey];
 }
 - (unsigned int)unsignedIntValueInComponent:(WOComponent *)_component {
   WOKeyPathComponent  *info;
   WOReturnValueHolder retValue;
     
   if (debugOn)
-    NSLog(@"%@: get uint value in component %@", self, _component);
+    [self logWithFormat:@"get uint value in component %@", _component];
   
   if (self->size > 1)
     return [_getValue(self, _component) unsignedIntValue];
@@ -1044,9 +1083,10 @@ static BOOL _setValue(WOKeyPathAssociation *self, id _value, id root) {
   }
 
 #if 0
-  NSLog(@"ret value object for key '%s' is 0x%08X",
-       info->ckey, retValue.object);
-  NSLog(@"ret value object class is %@", [retValue.object class]);
+  [self logWithFormat:@"ret value object for key '%s' is 0x%08X",
+       info->ckey, retValue.object];
+  [self logWithFormat:@"ret value object class is %@", 
+       [retValue.object class]];
 #endif
   return [retValue.object unsignedIntValue];
 }
@@ -1055,7 +1095,7 @@ static BOOL _setValue(WOKeyPathAssociation *self, id _value, id root) {
   WOKeyPathComponent *info;
   
   if (debugOn)
-    NSLog(@"%@: set int value %i in component %@", self, _value, _wo);
+    [self logWithFormat:@"set int value %i in component %@", _value, _wo];
   
   if (self->size > 1) {
     _setValue(self, intNumObj(_value), _wo);
@@ -1080,13 +1120,15 @@ static BOOL _setValue(WOKeyPathAssociation *self, id _value, id root) {
         switch (info->retType) {
           case _C_CHR: {
             if (((int)_value < -126) || ((int)_value > 127))
-              NSLog(@"%@: value (%i) out of range for char !", self, _value);
+              [self errorWithFormat:
+                     @"value (%i) out of range for char !", _value];
             sm.cmethod(_wo, setSel, (char)_value);
             break;
           }
           case _C_UCHR: {
             if ((_value < 0) || (_value > 255))
-              NSLog(@"%@: value (%i) out of range for uchar !", self, _value);
+              [self errorWithFormat:
+                     @"value (%i) out of range for uchar!", _value];
             sm.ucmethod(_wo, setSel, (unsigned char)_value);
             break;
           }
@@ -1127,14 +1169,14 @@ static BOOL _setValue(WOKeyPathAssociation *self, id _value, id root) {
     return;
   }
 
-  NSLog(@"%@: Could not set value for key '%s'.", self, info->ckey);
+  [self errorWithFormat:@"Could not set value for key '%s'.", info->ckey];
 }
 - (int)intValueInComponent:(WOComponent *)_component {
   WOKeyPathComponent  *info;
   WOReturnValueHolder retValue;
 
   if (debugOn)
-    NSLog(@"%@: get int value in component %@", self, _component);
+    [self logWithFormat:@"get int value in component %@", _component];
   
   if (self->size > 1)
     return [_getValue(self, _component) intValue];
@@ -1160,7 +1202,7 @@ static BOOL _setValue(WOKeyPathAssociation *self, id _value, id root) {
   WOKeyPathComponent *info;
   
   if (debugOn)
-    NSLog(@"%@: set bool value %i in component %@", self, _value, _wo);
+    [self logWithFormat:@"set bool value %i in component %@", _value, _wo];
   
   if (self->size > 1) {
     _setValue(self, [NumberClass numberWithBool:_value], _wo);
@@ -1224,13 +1266,12 @@ static BOOL _setValue(WOKeyPathAssociation *self, id _value, id root) {
       [_wo setValue:[NumberClass numberWithBool:_value]
            forBinding:info->extra.key];
   }
-  else {
-      NSLog(@"%@: Could not set value for key '%s'.", self, info->ckey);
-  }
+  else
+    [self errorWithFormat:@"Could not set value for key '%s'.", info->ckey];
 }
 - (BOOL)boolValueInComponent:(WOComponent *)_component {
   if (debugOn)
-    NSLog(@"%@: get bool value in component %@", self, _component);
+    [self logWithFormat:@"get bool value in component %@", _component];
   
   if (self->size > 1)
     return [_getValue(self, _component) boolValue];
@@ -1261,16 +1302,16 @@ static BOOL _setValue(WOKeyPathAssociation *self, id _value, id root) {
 
 - (void)setStringValue:(NSString *)_value inComponent:(WOComponent *)_wo {
   if (debugOn)
-    NSLog(@"%@: set string value '%@' in component %@", self, _value, _wo);
+    [self logWithFormat:@"set string value '%@' in component %@", _value, _wo];
   
   _setValue(self, _value, _wo);
 }
 - (NSString *)stringValueInComponent:(WOComponent *)_component {
   WOKeyPathComponent  *info;
   WOReturnValueHolder retValue;
-    
+  
   if (debugOn)
-    NSLog(@"%@: get string value in component %@", self, _component);
+    [self logWithFormat:@"get string value in component %@", _component];
   
   if (self->size > 1)
     return [_getValue(self, _component) stringValue];
@@ -1328,6 +1369,10 @@ static BOOL _setValue(WOKeyPathAssociation *self, id _value, id root) {
 
 /* description */
 
+- (NSString *)loggingPrefix {
+  return [StringClass stringWithFormat:@"|assoc=%@|", [self keyPath]];
+}
+
 - (NSString *)description {
   return [StringClass stringWithFormat:@"<%@[0x%08X]: keyPath=%@>",
                         NSStringFromClass([self class]), self,
index de1ac5f43388f04a5e069e2f4d1846d9a4aec715..3d5a8fa4e22464cda739ba9f8e0f36f03f4c7a3a 100644 (file)
@@ -1,7 +1,16 @@
+2006-03-12  Helge Hess  <helge.hess@opengroupware.org>
+
+       * SoObjects: added new class SoProductLoader which can be used to
+         load SoProduct bundles for a given application (v4.5.221)
+
 2006-02-26  Marcus Mueller  <znek@mulle-kybernetik.com>
 
        * NGObjWeb.xcodeproj: UnixSignalHandler.h is public now
 
+2006-02-23  Helge Hess  <helge.hess@opengroupware.org>
+
+       * Associations/WOKeyPathAssociation.m: use logging framework (v4.5.220)
+
 2006-02-22  Helge Hess  <helge.hess@opengroupware.org>
 
        * WOComponent.m, WODirectAction.m, DynamicElements/WOBrowser.m: minor
index 993d63795a3632e8d87c3bfc85757fda5e0472b3..2ee8983fd8a324da0ae211ae90f347b1063b8aeb 100644 (file)
@@ -40,6 +40,7 @@ SoObjects_HEADER_FILES = \
        SoSubContext.h                  \
        SoSecurityException.h           \
        SoComponent.h                   \
+       SoProductLoader.h               \
 
 SoObjects_OBJC_FILES = \
        NSException+HTTP.m              \
@@ -77,6 +78,7 @@ SoObjects_OBJC_FILES = \
        SoSubContext.m                  \
        SoSecurityException.m           \
        SoComponent.m                   \
+       SoProductLoader.m               \
 
 -include GNUmakefile.preamble
 include $(GNUSTEP_MAKEFILES)/subproject.make
diff --git a/sope-appserver/NGObjWeb/SoObjects/SoProductLoader.h b/sope-appserver/NGObjWeb/SoObjects/SoProductLoader.h
new file mode 100644 (file)
index 0000000..ecfcf08
--- /dev/null
@@ -0,0 +1,35 @@
+/*
+  Copyright (C) 2006 Helge Hess
+*/
+
+#ifndef __SoProductLoader_H__
+#define __SoProductLoader_H__
+
+#import <Foundation/NSObject.h>
+
+/*
+  SoProductLoader
+
+  This class is for loading SOPE products for a given application.
+  
+  TODO: document
+*/
+
+@class NSString, NSArray;
+
+@interface SoProductLoader : NSObject
+{
+  NSString *productDirectoryName;
+  NSArray  *searchPathes;
+}
+
+- (id)initWithAppName:(NSString *)_appName
+  majorVersion:(NSString *)_mav minorVersion:(NSString *)_miv;
+
+/* operations */
+
+- (void)loadProducts;
+
+@end
+
+#endif /* __SoProductLoader_H__ */
diff --git a/sope-appserver/NGObjWeb/SoObjects/SoProductLoader.m b/sope-appserver/NGObjWeb/SoObjects/SoProductLoader.m
new file mode 100644 (file)
index 0000000..b7abe11
--- /dev/null
@@ -0,0 +1,153 @@
+/*
+  Copyright (C) 2006 Helge Hess
+*/
+
+#include "SoProductLoader.h"
+#include "SoProductRegistry.h"
+#include "common.h"
+
+@implementation SoProductLoader
+
+- (id)initWithAppName:(NSString *)_appName
+  majorVersion:(NSString *)_mav minorVersion:(NSString *)_miv
+{
+  if ((self = [super init]) != nil) {
+    if (![_appName isNotEmpty]) {
+      [self release];
+      return nil;
+    }
+    
+    self->productDirectoryName =
+      [[NSString alloc] initWithFormat:@"%@-%i.%i", _appName, _mav, _miv];
+  }
+  return self;
+}
+
+- (void)dealloc {
+  [self->productDirectoryName release];
+  [self->searchPathes         release];
+  [super dealloc];
+}
+
+/* loading */
+
+- (void)_addCocoaSearchPathesToArray:(NSMutableArray *)ma {
+  id tmp;
+
+  tmp = NSSearchPathForDirectoriesInDomains(NSAllLibrariesDirectory,
+                                            NSAllDomainsMask,
+                                            YES);
+  if ([tmp count] > 0) {
+    NSEnumerator *e;
+      
+    e = [tmp objectEnumerator];
+    while ((tmp = [e nextObject])) {
+      tmp = [tmp stringByAppendingPathComponent:self->productDirectoryName];
+      if (![ma containsObject:tmp])
+        [ma addObject:tmp];
+    }
+  }
+}
+
+- (void)_addGNUstepSearchPathesToArray:(NSMutableArray *)ma {
+  NSDictionary *env;
+  id tmp;
+  
+  env = [[NSProcessInfo processInfo] environment];
+  if ((tmp = [env objectForKey:@"GNUSTEP_PATHPREFIX_LIST"]) == nil)
+    tmp = [env objectForKey:@"GNUSTEP_PATHLIST"];
+  
+  tmp = [tmp componentsSeparatedByString:@":"];
+  if ([tmp count] > 0) {
+    NSEnumerator *e;
+      
+    e = [tmp objectEnumerator];
+    while ((tmp = [e nextObject]) != nil) {
+      tmp = [tmp stringByAppendingPathComponent:@"Library"];
+      tmp = [tmp stringByAppendingPathComponent:self->productDirectoryName];
+      if (![ma containsObject:tmp])
+        [ma addObject:tmp];
+    }
+  }
+  else {
+    [self logWithFormat:@"%s: empty library search path !", 
+         __PRETTY_FUNCTION__];
+  }
+}
+
+- (void)_addFHSPathesToArray:(NSMutableArray *)ma {
+  NSString *s;
+  
+  s = [self->productDirectoryName lowercaseString];
+  [ma addObject:[@"/usr/local/lib/" stringByAppendingString:s]];
+  [ma addObject:[@"/usr/lib/"       stringByAppendingString:s]];
+}
+
+- (NSArray *)productSearchPathes {
+  NSMutableArray *ma;
+  BOOL hasGNUstepEnv;
+  
+  if (self->searchPathes != nil)
+    return self->searchPathes;
+
+  hasGNUstepEnv = [[[[NSProcessInfo processInfo] environment]
+                    objectForKey:@"GNUSTEP_USER_ROOT"] length] > 0 ? YES : NO;
+  
+  ma  = [NSMutableArray arrayWithCapacity:6];
+  
+  if (hasGNUstepEnv)
+    [self _addGNUstepSearchPathesToArray:ma];
+#if COCOA_Foundation_LIBRARY
+  else
+    [self _addCocoaSearchPathesToArray:ma];
+#endif
+
+  [self _addFHSPathesToArray:ma];
+  
+  self->searchPathes = [ma copy];
+  
+  if ([self->searchPathes count] == 0) {
+    [self logWithFormat:@"%s: no search pathes were found !", 
+         __PRETTY_FUNCTION__];
+  }
+  
+  return self->searchPathes;
+}
+
+- (void)loadProducts {
+  SoProductRegistry *registry = nil;
+  NSFileManager *fm;
+  NSEnumerator  *pathes;
+  NSString      *lpath;
+  
+  registry = [SoProductRegistry sharedProductRegistry];
+  fm       = [NSFileManager defaultManager];
+  
+  pathes = [[self productSearchPathes] objectEnumerator];
+  while ((lpath = [pathes nextObject]) != nil) {
+    NSEnumerator *productNames;
+    NSString *productName;
+    
+    [self logWithFormat:@"scanning for products in: %@", lpath];
+
+    productNames = [[fm directoryContentsAtPath:lpath] objectEnumerator];
+    
+    while ((productName = [productNames nextObject]) != nil) {
+      NSString *bpath;
+
+      if ([[productName pathExtension] length] == 0)
+       /* filter out directories without extensions */
+       continue;
+      
+      bpath = [lpath stringByAppendingPathComponent:productName];
+      [self logWithFormat:@"  register product: %@", 
+              [bpath lastPathComponent]];
+      [registry registerProductAtPath:bpath];
+    }
+  }
+  
+  if (![registry loadAllProducts])
+    [self warnWithFormat:@"could not load all products !"];
+}
+
+@end /* SoProductLoader */
index 0803e2fa4aaa6d37787363bdb0d2ff12737f1d67..125b313c24193e7062ffe9d853733a2eeb501212 100644 (file)
@@ -1,6 +1,6 @@
 # version file
 
-SUBMINOR_VERSION:=219
+SUBMINOR_VERSION:=221
 
 # v4.5.214 requires libNGExtensions v4.5.179
 # v4.5.122 requires libNGExtensions v4.5.153
index e188d7a1ef0b9954e3a2777ac06f26e2b384053c..649e13868f8e99021e0c54c08ed115945558d66b 100644 (file)
@@ -1085,7 +1085,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;
@@ -1095,6 +1095,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
@@ -1102,7 +1106,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;
@@ -1117,14 +1121,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];
 }