From: helge Date: Sun, 12 Mar 2006 20:33:46 +0000 (+0000) Subject: use logging framework in WOKeyPathAssociation X-Git-Url: https://err.no/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=4d2c35c7c6a64ebf07aed079fc7462b2792247c3;p=sope use logging framework in WOKeyPathAssociation added SoProductLoader class to load SoProduct bundles git-svn-id: http://svn.opengroupware.org/SOPE/trunk@1223 e4a50df8-12e2-0310-a44c-efbce7f8a7e3 --- diff --git a/sope-appserver/NGObjWeb/Associations/WOKeyPathAssociation.m b/sope-appserver/NGObjWeb/Associations/WOKeyPathAssociation.m index 61d7ad1b..fd06a27e 100644 --- a/sope-appserver/NGObjWeb/Associations/WOKeyPathAssociation.m +++ b/sope-appserver/NGObjWeb/Associations/WOKeyPathAssociation.m @@ -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) : @""); + setSel ? NSStringFromSelector(setSel) : @""]; #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, diff --git a/sope-appserver/NGObjWeb/ChangeLog b/sope-appserver/NGObjWeb/ChangeLog index de1ac5f4..3d5a8fa4 100644 --- a/sope-appserver/NGObjWeb/ChangeLog +++ b/sope-appserver/NGObjWeb/ChangeLog @@ -1,7 +1,16 @@ +2006-03-12 Helge Hess + + * 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 * NGObjWeb.xcodeproj: UnixSignalHandler.h is public now +2006-02-23 Helge Hess + + * Associations/WOKeyPathAssociation.m: use logging framework (v4.5.220) + 2006-02-22 Helge Hess * WOComponent.m, WODirectAction.m, DynamicElements/WOBrowser.m: minor diff --git a/sope-appserver/NGObjWeb/SoObjects/GNUmakefile b/sope-appserver/NGObjWeb/SoObjects/GNUmakefile index 993d6379..2ee8983f 100644 --- a/sope-appserver/NGObjWeb/SoObjects/GNUmakefile +++ b/sope-appserver/NGObjWeb/SoObjects/GNUmakefile @@ -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 index 00000000..ecfcf086 --- /dev/null +++ b/sope-appserver/NGObjWeb/SoObjects/SoProductLoader.h @@ -0,0 +1,35 @@ +/* + Copyright (C) 2006 Helge Hess +*/ + +#ifndef __SoProductLoader_H__ +#define __SoProductLoader_H__ + +#import + +/* + 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 index 00000000..b7abe117 --- /dev/null +++ b/sope-appserver/NGObjWeb/SoObjects/SoProductLoader.m @@ -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 */ diff --git a/sope-appserver/NGObjWeb/Version b/sope-appserver/NGObjWeb/Version index 0803e2fa..125b313c 100644 --- a/sope-appserver/NGObjWeb/Version +++ b/sope-appserver/NGObjWeb/Version @@ -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 diff --git a/sope-appserver/NGObjWeb/WOComponent.m b/sope-appserver/NGObjWeb/WOComponent.m index e188d7a1..649e1386 100644 --- a/sope-appserver/NGObjWeb/WOComponent.m +++ b/sope-appserver/NGObjWeb/WOComponent.m @@ -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 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]; }