From: helge Date: Mon, 22 Aug 2005 22:12:41 +0000 (+0000) Subject: added new WOCopyValue element X-Git-Url: https://err.no/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=2f5c4aa262fe2e917dd8b26cb3075f187ec31186;p=sope added new WOCopyValue element fixed a bug in the DG fixed some dependency git-svn-id: http://svn.opengroupware.org/SOPE/trunk@1063 e4a50df8-12e2-0310-a44c-efbce7f8a7e3 --- diff --git a/sope-appserver/NGObjWeb/ChangeLog b/sope-appserver/NGObjWeb/ChangeLog index 8c40f1a1..ad16c9bf 100644 --- a/sope-appserver/NGObjWeb/ChangeLog +++ b/sope-appserver/NGObjWeb/ChangeLog @@ -1,13 +1,34 @@ -2005-08-19 Helge Hess +2005-08-23 Helge Hess + + * v4.5.190 + + * GNUmakefile.preamble: added NGMail framework dependency + + * WODisplayGroup.m: fixed an issue with processing max qualifiers + +2005-08-22 Helge Hess + + * v4.5.189 + + * DynamicElements/WOxComponentElemBuilder.m: expose WOCopyValue as + in WOx + + * DynamicElements: added WOCopyValue dynamic element, this renders + nothing and is used to copy KVC values at certain times during the + template evaluation + +2005-08-19 Helge Hess * v4.5.188 - * WebDAV/SoObjectWebDAVDispatcher.m: reuse root-url construction method in SoObject.m + * WebDAV/SoObjectWebDAVDispatcher.m: reuse root-url construction + method in SoObject.m - * WebDAV/SoObjectDataSource.m, WebDAV/SoObjectResultEntry.m: removed two aborts + * WebDAV/SoObjectDataSource.m, WebDAV/SoObjectResultEntry.m: removed + two aborts - * SoObjects/SoObject.m: added a hack to deal with buggy Debian apachessl (#1435), - moved root-url construction method to a function + * SoObjects/SoObject.m: added a hack to deal with buggy Debian + apachessl (#1435), moved root-url construction method to a function 2005-08-16 Helge Hess diff --git a/sope-appserver/NGObjWeb/DynamicElements/GNUmakefile b/sope-appserver/NGObjWeb/DynamicElements/GNUmakefile index 0a73c0be..ba5464a0 100644 --- a/sope-appserver/NGObjWeb/DynamicElements/GNUmakefile +++ b/sope-appserver/NGObjWeb/DynamicElements/GNUmakefile @@ -53,6 +53,7 @@ DynamicElements_OBJC_FILES = \ WOVBScript.m \ WOEntity.m \ WOSetCursor.m \ + WOCopyValue.m \ \ WONoContentElement.m \ _WOStaticHTMLElement.m \ @@ -67,8 +68,8 @@ DynamicElements_OBJC_FILES += \ _WOCommonStaticDAHyperlink.m \ _WOSimpleActionHyperlink.m \ -$(GNUSTEP_OBJ_DIR)/WOGenericContainer.o : WOGenericElement.h WOGenericElement.m WOGenericContainer.m - -include GNUmakefile.preamble include $(GNUSTEP_MAKEFILES)/subproject.make -include GNUmakefile.postamble + +$(GNUSTEP_OBJ_DIR)/WOGenericContainer.o : WOGenericElement.h WOGenericElement.m WOGenericContainer.m diff --git a/sope-appserver/NGObjWeb/DynamicElements/WOCopyValue.api b/sope-appserver/NGObjWeb/DynamicElements/WOCopyValue.api new file mode 100644 index 00000000..8ba64e81 --- /dev/null +++ b/sope-appserver/NGObjWeb/DynamicElements/WOCopyValue.api @@ -0,0 +1,4 @@ + + + + diff --git a/sope-appserver/NGObjWeb/DynamicElements/WOCopyValue.m b/sope-appserver/NGObjWeb/DynamicElements/WOCopyValue.m new file mode 100644 index 00000000..deb34798 --- /dev/null +++ b/sope-appserver/NGObjWeb/DynamicElements/WOCopyValue.m @@ -0,0 +1,278 @@ +/* + Copyright (C) 2005 SKYRIX Software AG + + This file is part of SOPE. + + SOPE is free software; you can redistribute it and/or modify it under + the terms of the GNU Lesser General Public License as published by the + Free Software Foundation; either version 2, or (at your option) any + later version. + + SOPE is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public + License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with SOPE; see the file COPYING. If not, write to the + Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA + 02111-1307, USA. +*/ + +#include + +/* + WOCopyValue / + + Usage: + SetupContext: WOCopyValue { + currentDate = "currentItem.date"; + copyValues = { + "displayGroup.queryMin.lastModified" = "currentItem.date"; + "displayGroup.queryMax.lastModified" = "currentItem.date"; + }; + finishValues = { + "displayGroup.queryMin.lastModified" = nil; + "displayGroup.queryMax.lastModified" = nil; + }; + resetValues = NO; + } + + Bindings: + copyValues + finishValues + resetValues + : are used as 'prepare' values + + The element has a template and can be used in a certain scope, +*/ + +@interface WOCopyValue : WODynamicElement // TODO: should be WOElement? +{ + WOAssociation **targets; + WOAssociation **sources; + unsigned count; + WOElement *template; + WOAssociation *copyValues; + WOAssociation *finishValues; + WOAssociation *resetValues; +} + +@end + +#include +#include +#include "common.h" + +@implementation WOCopyValue + +// TODO: cache NSString class, cache constant objects + +static inline id valueForConstString(NSString *v) { + unsigned len; + unichar c0; + id vr; + + len = [v length]; + c0 = len > 6 ? [v characterAtIndex:6] : 0; + + if ((len == 9 && c0 == 'n' && [v isEqualToString:@"const:nil"]) || + (len == 10 && c0 == 'n' && [v isEqualToString:@"const:null"])) { + vr = [NSNull null]; + } + else if ((len == 9 && c0 == 'y' && [v isEqualToString:@"const:yes"]) || + (len == 10 && c0 == 't' && [v isEqualToString:@"const:true"])) { + vr = [NSNumber numberWithBool:NO]; + } + else if ((len == 8 && c0 == 'n' && [v isEqualToString:@"const:no"]) || + (len == 11 && c0 == 'f' && [v isEqualToString:@"const:false"])) { + vr = [NSNumber numberWithBool:NO]; + } + else if (isdigit(c0) || (c0 == '-' && len > 7)) { + vr = [v substringFromIndex:6]; + vr = ([vr rangeOfString:@"."].length > 0) + ? [NSNumber numberWithDouble:[vr doubleValue]] + : [NSNumber numberWithDouble:[vr intValue]]; + } + else + vr = [v substringFromIndex:6]; + + return vr; +} + +- (id)initWithName:(NSString *)_name + associations:(NSDictionary *)_config + template:(WOElement *)_c +{ + if ((self = [super initWithName:_name associations:_config template:_c])) { + NSDictionary *statVals; + + self->template = [_c retain]; + self->copyValues = OWGetProperty(_config, @"copyValues"); + self->finishValues = OWGetProperty(_config, @"finishValues"); + self->resetValues = OWGetProperty(_config, @"resetValues"); + + /* fill static value array */ + + if ([self->copyValues isValueConstant]) { + statVals = [[self->copyValues valueInContext:nil] retain]; + [self->copyValues release]; + self->copyValues = nil; + } + + if ((self->count = ([statVals count] + [_config count])) > 0) { + NSEnumerator *e; + NSString *key; + unsigned i; + + self->targets = calloc(self->count + 2, sizeof(id)); + self->sources = calloc(self->count + 2, sizeof(id)); + i = 0; + + /* extra keys first (key is a string, value is an assoc) */ + + e = [_config keyEnumerator]; + while ((key = [e nextObject]) != nil) { + self->targets[i] = [[WOAssociation associationWithKeyPath:key] retain]; + self->sources[i] = [[_config objectForKey:key] retain]; + i++; + } + + /* then static keys (key and value are strings) */ + + e = [statVals keyEnumerator]; + while ((key = [e nextObject]) != nil) { + NSString *v; + + v = [statVals objectForKey:key]; + self->targets[i] = [[WOAssociation associationWithKeyPath:key] retain]; + + if ([v hasPrefix:@"const:"]) { + self->sources[i] = + [[WOAssociation associationWithValue:valueForConstString(v)] + retain]; + } + else { + self->sources[i] = + [[WOAssociation associationWithKeyPath:v] retain]; + } + i++; + } + } + + [statVals release]; statVals = nil; + } + return self; +} + +- (void)dealloc { + unsigned i; + + [self->finishValues release]; + [self->resetValues release]; + + for (i = 0; i < self->count; i++) { + [self->targets[i] release]; + [self->sources[i] release]; + } + if (self->targets != NULL) free(self->targets); + if (self->sources != NULL) free(self->sources); + + [self->template release]; + [super dealloc]; +} + +/* accessors */ + +- (id)template { + return self->template; +} + +/* copy */ + +- (void)copyValuesInDictionary:(NSDictionary *)_d inContext:(WOContext *)_ctx { + NSEnumerator *e; + NSString *key; + id setCursor, getCursor; + + setCursor = [_ctx component]; + getCursor = setCursor; + + e = [_d keyEnumerator]; + while ((key = [e nextObject]) != nil) { + id value; + + value = [_d objectForKey:key]; + if ([value isKindOfClass:[NSString class]]) { + value = [value hasPrefix:@"const:"] + ? valueForConstString(value) + : [getCursor valueForKeyPath:value]; + } + + [setCursor takeValue:value forKeyPath:key]; + } +} + +- (void)copyValuesInContext:(WOContext *)_ctx { + unsigned i; + + /* copy constant mappings */ + for (i = 0; i < self->count; i++) { + [self->targets[i] setValue:[self->sources[i] valueInContext:_ctx] + inContext:_ctx]; + } + + /* copy dynamic mappings */ + if (self->copyValues != nil) { + [self copyValuesInDictionary:[self->copyValues valueInContext:_ctx] + inContext:_ctx]; + } +} + +- (void)resetValuesInContext:(WOContext *)_ctx { + if (self->resetValues == nil && self->finishValues == nil) + return; + + /* reset values to nil */ + + if ([self->resetValues boolValueInContext:_ctx]) { + unsigned i; + + for (i = 0; i < self->count; i++) + [self->targets[i] setValue:nil inContext:_ctx]; + } + + /* apply post value copy */ + if (self->finishValues != nil) { + [self copyValuesInDictionary:[self->finishValues valueInContext:_ctx] + inContext:_ctx]; + } +} + +/* handling requests */ + +- (void)takeValuesFromRequest:(WORequest *)_rq inContext:(WOContext *)_ctx { + [self copyValuesInContext:_ctx]; + [self->template takeValuesFromRequest:_rq inContext:_ctx]; + [self resetValuesInContext:_ctx]; +} + +- (id)invokeActionForRequest:(WORequest *)_rq inContext:(WOContext *)_ctx { + id result; + + [self copyValuesInContext:_ctx]; + result = [[self->template invokeActionForRequest:_rq inContext:_ctx] retain]; + [self resetValuesInContext:_ctx]; + + return [result autorelease]; +} + +/* generating response */ + +- (void)appendToResponse:(WOResponse *)_response inContext:(WOContext *)_ctx { + [self copyValuesInContext:_ctx]; + [self->template appendToResponse:_response inContext:_ctx]; + [self resetValuesInContext:_ctx]; +} + +@end /* WOCopyValue */ diff --git a/sope-appserver/NGObjWeb/DynamicElements/WOxControlElemBuilder.m b/sope-appserver/NGObjWeb/DynamicElements/WOxControlElemBuilder.m index 4c456077..6424b7c2 100644 --- a/sope-appserver/NGObjWeb/DynamicElements/WOxControlElemBuilder.m +++ b/sope-appserver/NGObjWeb/DynamicElements/WOxControlElemBuilder.m @@ -26,10 +26,11 @@ repetitions. Supported tags: - maps to WOConditional - maps to WOConditional - maps to WORepetition - maps to WOSetCursor + maps to WOConditional + maps to WOConditional + maps to WORepetition + maps to WOSetCursor + maps to WOCopyValue */ @interface WOxControlElemBuilder : WOxTagClassElemBuilder @@ -46,6 +47,8 @@ - (Class)classForElement:(id)_element { NSString *nsuri; NSString *tag; + unsigned len; + unichar c0; if (_element == nil) return nil; @@ -54,28 +57,45 @@ return Nil; tag = [_element tagName]; - - if ([tag isEqualToString:@"if"] || - [tag isEqualToString:@"if-not"] || [tag isEqualToString:@"ifnot"]) { + len = [tag length]; + c0 = len > 0 ? [tag characterAtIndex:0] : 0; + + if (c0 == 'i' && len > 1 && + ((len == 2 && [tag isEqualToString:@"if"]) || + (len == 6 && [tag isEqualToString:@"if-not"]) || + (len == 5 && [tag isEqualToString:@"ifnot"]))) { static Class clazz = Nil; if (clazz == Nil) clazz = NSClassFromString(@"WOConditional"); + + if (len > 2) + [self logWithFormat:@"WARNING: if-not/ifnot not supported!"]; + return clazz; } - if ([tag isEqualToString:@"foreach"] || [tag isEqualToString:@"for-each"]) { + if (c0 == 'f' && len > 6 && + ([tag isEqualToString:@"foreach"] || [tag isEqualToString:@"for-each"])){ static Class clazz = Nil; if (clazz == Nil) clazz = NSClassFromString(@"WORepetition"); return clazz; } - if ([tag isEqualToString:@"with"]) { + + if (c0 == 'w' && len == 4 && [tag isEqualToString:@"with"]) { static Class clazz = Nil; if (clazz == Nil) clazz = NSClassFromString(@"WOSetCursor"); return clazz; } + if (c0 == 'c' && len == 10 && [tag isEqualToString:@"copy-value"]) { + static Class clazz = Nil; + if (clazz == Nil) + clazz = NSClassFromString(@"WOCopyValue"); + return clazz; + } + return Nil; } diff --git a/sope-appserver/NGObjWeb/GNUmakefile.preamble b/sope-appserver/NGObjWeb/GNUmakefile.preamble index 6d02aeb8..6150111f 100644 --- a/sope-appserver/NGObjWeb/GNUmakefile.preamble +++ b/sope-appserver/NGObjWeb/GNUmakefile.preamble @@ -55,10 +55,11 @@ SYSTEM_LIB_DIR += -L/usr/local/lib -L/usr/lib # dependencies libNGObjWeb_LIBRARIES_DEPEND_UPON += \ - -lNGMime -lNGStreams -lNGExtensions -lEOControl \ + -lNGMime \ + -lNGStreams -lNGExtensions -lEOControl \ -lXmlRpc -lDOM -lSaxObjC NGObjWeb_LIBRARIES_DEPEND_UPON += \ - -framework NGMime \ + -framework NGMime -framework NGMail \ -framework NGStreams -framework NGExtensions -framework EOControl \ -framework XmlRpc -framework DOM -framework SaxObjC diff --git a/sope-appserver/NGObjWeb/Version b/sope-appserver/NGObjWeb/Version index a154504c..13088ca4 100644 --- a/sope-appserver/NGObjWeb/Version +++ b/sope-appserver/NGObjWeb/Version @@ -1,6 +1,6 @@ # version file -SUBMINOR_VERSION:=188 +SUBMINOR_VERSION:=190 # v4.5.122 requires libNGExtensions v4.5.153 # v4.5.91 requires libNGExtensions v4.5.134 diff --git a/sope-appserver/NGObjWeb/WODisplayGroup.m b/sope-appserver/NGObjWeb/WODisplayGroup.m index b727b80b..31f7710e 100644 --- a/sope-appserver/NGObjWeb/WODisplayGroup.m +++ b/sope-appserver/NGObjWeb/WODisplayGroup.m @@ -631,7 +631,7 @@ static NSArray *uint0Array = nil; /* construct qualifier for all query-match entries */ keys = [qm keyEnumerator]; - while ((key = [keys nextObject])) { + while ((key = [keys nextObject]) != nil) { NSString *op; SEL ops; id value; @@ -684,13 +684,13 @@ static NSArray *uint0Array = nil; } /* construct max qualifiers */ - + keys = [qmax keyEnumerator]; while ((key = [keys nextObject]) != nil) { EOQualifier *q; id value; - value = [qmin objectForKey:key]; + value = [qmax objectForKey:key]; q = [[EOKeyValueQualifier alloc] initWithKey:key @@ -814,7 +814,7 @@ static NSArray *uint0Array = nil; if ((q = [self qualifierFromQueryValues]) != nil) [self setQualifier:q]; - + if ([ds respondsToSelector:@selector(setAuxiliaryQualifier:)]) [ds setAuxiliaryQualifier:[self qualifier]]; else if ([ds respondsToSelector:@selector(setQualifier:)])