X-Git-Url: https://err.no/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=sope-appserver%2FNGObjWeb%2FTemplates%2FWOxElemBuilder.m;h=af29e83fd64e01c5e5bcc3836f6d3ab418083268;hb=a2987d1ae925a5e7145fd2aa8827d86c06b12ce9;hp=ca5d725c4fce6e5995c3c327d38e068c6dd0fa32;hpb=770a77ee455ed03dbca084e56386d50e8bcffcc2;p=sope diff --git a/sope-appserver/NGObjWeb/Templates/WOxElemBuilder.m b/sope-appserver/NGObjWeb/Templates/WOxElemBuilder.m index ca5d725c..af29e83f 100644 --- a/sope-appserver/NGObjWeb/Templates/WOxElemBuilder.m +++ b/sope-appserver/NGObjWeb/Templates/WOxElemBuilder.m @@ -1,20 +1,20 @@ /* - Copyright (C) 2000-2004 SKYRIX Software AG + Copyright (C) 2000-2005 SKYRIX Software AG - This file is part of OpenGroupware.org. + This file is part of SOPE. - OGo is free software; you can redistribute it and/or modify it under + 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. - OGo is distributed in the hope that it will be useful, but WITHOUT ANY + 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 OGo; see the file COPYING. If not, write to the + 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. */ @@ -26,11 +26,14 @@ #include #include #include +#include #include "WOComponentFault.h" #include "common.h" @interface WOElement(UsedPrivates) - (id)initWithValue:(id)_value escapeHTML:(BOOL)_flag; ++ (id)allocForCount:(int)_count zone:(NSZone *)_zone; +- (id)initWithContentElements:(NSArray *)_elements; @end @interface WOAssociation(misc) @@ -71,7 +74,7 @@ /* operations */ -- (WOComponent *)instantiateWithResourceManager:(WOResourceManager *)_rm +- (id)instantiateWithResourceManager:(WOResourceManager *)_rm languages:(NSArray *)_languages { static Class FaultClass = Nil; @@ -94,46 +97,70 @@ @implementation WOxElemBuilder -static Class StrClass = Nil; -static Class AStrClass = Nil; -static NSDictionary *defaultAssocMap = nil; -static Class ValAssoc = Nil; -static BOOL logAssocMap = NO; -static BOOL logAssocCreation = NO; -static BOOL debugOn = NO; +static Class StrClass = Nil; +static Class AStrClass = Nil; +static NSDictionary *defaultAssocMap = nil; +static Class ValAssoc = Nil; +static BOOL logAssocMap = NO; +static BOOL logAssocCreation = NO; +static BOOL debugOn = NO; +static NGLogger *logger = nil; +static Class CompoundElemClass = Nil; +static NSNumber *yesNum = nil; +static WOAssociation *yesAssoc = nil; + (int)version { return 1; } + (void)initialize { - NSUserDefaults *ud = [NSUserDefaults standardUserDefaults]; + NSUserDefaults *ud; + NGLoggerManager *lm; static BOOL didInit = NO; + if (didInit) return; didInit = YES; - + + ud = [NSUserDefaults standardUserDefaults]; + lm = [NGLoggerManager defaultLoggerManager]; + + logger = [lm loggerForClass:self]; + [logger setLogLevel:[WOApplication isDebuggingEnabled] ? NGLogLevelDebug + : NGLogLevelInfo]; + StrClass = NSClassFromString(@"_WOSimpleStaticString"); if (StrClass == Nil) - NSLog(@"ERROR: missing class _WOSimpleStaticString !"); + [logger errorWithFormat:@"missing class _WOSimpleStaticString !"]; AStrClass = NSClassFromString(@"_WOSimpleStaticASCIIString"); if (AStrClass == Nil) - NSLog(@"ERROR: missing class _WOSimpleStaticASCIIString !"); + [logger errorWithFormat:@"missing class _WOSimpleStaticASCIIString !"]; logAssocMap = [ud boolForKey:@"WOxElemBuilder_LogAssociationMapping"]; logAssocCreation = [ud boolForKey:@"WOxElemBuilder_LogAssociationCreation"]; - if (logAssocMap) NSLog(@"Note: association mapping is logged!"); - if (logAssocCreation) NSLog(@"Note: association creation is logged!"); - + if (logAssocMap) + [logger logWithFormat:@"association mapping is logged!"]; + if (logAssocCreation) + [logger logWithFormat:@"association creation is logged!"]; + + // TODO: improve extensibility of this (remember WOWrapperTemplateBuilder) defaultAssocMap = [[ud dictionaryForKey:@"WOxAssociationClassMapping"] copy]; if (defaultAssocMap == nil) - NSLog(@"WARNING: WOxAssociationClassMapping default is not set!"); + [logger warnWithFormat: + @"WOxAssociationClassMapping default is not set!"]; if (ValAssoc == Nil) ValAssoc = NSClassFromString(@"WOValueAssociation"); + + CompoundElemClass = NSClassFromString(@"WOCompoundElement"); + + if (yesNum == nil) + yesNum = [[NSNumber numberWithBool:YES] retain]; + if (yesAssoc == nil) + yesAssoc = [[WOAssociation associationWithValue:yesNum] retain]; } + (WOxElemBuilder *)createBuilderQueue:(NSArray *)_classNames { - unsigned i, count; + unsigned i, count; WOxElemBuilder *first, *current = nil; NSMutableArray *missingBuilders = nil; @@ -383,21 +410,20 @@ static BOOL debugOn = NO; c = [self associationClassForNamespaceURI:[_attribute namespaceURI]]; if (c == Nil) { - [self logWithFormat: - @"WARNING, found no association class for " - @"attribute %@ (namespace=%@)", + [self warnWithFormat: + @"found no association class for attribute %@ (namespace=%@)", _attribute, [_attribute namespaceURI]]; return nil; } if (logAssocMap) { [self logWithFormat:@"use class %@ for namespaceURI %@ (attribute %@)", - c, [_attribute namespaceURI], [_attribute name]]; + c, [_attribute namespaceURI], [_attribute name]]; } assoc = [[c alloc] initWithString:value]; if (logAssocCreation) { [self logWithFormat:@"created assoc %@ for attribute %@", - assoc, [_attribute name]]; + assoc, [_attribute name]]; } return [assoc autorelease]; @@ -440,7 +466,7 @@ static BOOL debugOn = NO; self->nsToAssoc = [[NSMutableDictionary alloc] initWithCapacity:8]; e = [defaultAssocMap keyEnumerator]; - while ((ns = [e nextObject])) { + while ((ns = [e nextObject]) != nil) { NSString *className; Class clazz; @@ -448,7 +474,7 @@ static BOOL debugOn = NO; clazz = NSClassFromString(className); if (clazz == Nil) { - [self logWithFormat:@"WARNING: did not find association class: '%@'", + [self warnWithFormat:@"did not find association class: '%@'", className]; continue; } @@ -469,7 +495,7 @@ static BOOL debugOn = NO; [self _ensureDefaultAssocMappings]; - if ((c = [self->nsToAssoc objectForKey:_ns]) == nil) + if ((c = [self->nsToAssoc objectForKey:_ns]) == Nil) /* if we have no class mapped for a namespace, we treat it as a value */ c = ValAssoc; @@ -530,6 +556,13 @@ static BOOL debugOn = NO; /* logging */ ++ (id)logger { + return logger; +} +- (id)logger { + return logger; +} + - (void)logWithFormat:(NSString *)_format, ... { NSString *value = nil; va_list ap; @@ -614,31 +647,134 @@ static BOOL debugOn = NO; - (void)reset { [self->subcomponentInfos removeAllObjects]; - ASSIGN(self->script, (id)nil); + [self->script release]; self->script = nil; } -@end /* WOxElemBuilder */ +/* support methods for subclasses */ -@implementation WOxTagClassElemBuilder +- (id)lookupUniqueTag:(NSString *)_name + inElement:(id)_elem +{ + id list; + + if ((list = [_elem getElementsByTagName:_name]) == nil) + return nil; + if ([list length] == 0) + return nil; + if ([list length] > 1) { + [self warnWithFormat: + @"more than once occurence of tag %@ in element: %@", + _name, _elem]; + } + return [list objectAtIndex:0]; +} -- (Class)classForElement:(id)_element { - return Nil; +- (WOElement *)elementForRawString:(NSString *)_rawstr { + /* Note: returns a retained element! */ + WOAssociation *a; + + if (_rawstr == nil) return nil; + a = [WOAssociation associationWithValue:_rawstr]; + return [[StrClass alloc] initWithValue:a escapeHTML:NO]; } -- (WOElement *)buildElement:(id)_element templateBuilder:(id)_b { - Class clazz; +- (WOElement *)elementForElementsAndStrings:(NSArray *)_elements { + /* Note: returns a retained element! */ + NSMutableArray *ma; + WOElement *element; + unsigned i, count; - if ((clazz = [self classForElement:_element]) == Nil) { - if (self->nextBuilder) - return [self->nextBuilder buildElement:_element templateBuilder:_b]; - else { - [self logWithFormat: - @"did not find dynamic element class for DOM element %@", - _element]; - return nil; + if ((count = [_elements count]) == 0) + return nil; + + ma = [[NSMutableArray alloc] initWithCapacity:count]; + for (i = 0; i < count; i++) { + id elem; + + elem = [_elements objectAtIndex:i]; + if ([elem isKindOfClass:[WOElement class]]) { + [ma addObject:elem]; + continue; } + + if ((elem = [self elementForRawString:[elem stringValue]])) + [ma addObject:elem]; + } + if ((count = [ma count]) == 0) + element = nil; + else if (count == 1) { + element = [[ma objectAtIndex:0] retain]; + } + else { + element = [[CompoundElemClass allocForCount:count zone:NULL] + initWithContentElements:ma]; + } + [ma release]; + return element; +} + +- (WOElement *)wrapElement:(WOElement *)_element + inCondition:(WOAssociation *)_condition + negate:(BOOL)_flag +{ + // NOTE: *releases* _element parameter! + // returns retained conditional + static Class WOConditionalClass = Nil; + static NSString *key = @"condition"; + NSMutableDictionary *assocs; + WOElement *element; + NSArray *children; + + if (WOConditionalClass == Nil) + WOConditionalClass = NSClassFromString(@"WOConditional"); + + if (_element == nil) + return nil; + if (_condition == nil) + return _element; + + if (_flag) { + assocs = [[NSMutableDictionary alloc] + initWithObjectsAndKeys:_condition, key, + yesAssoc, @"negate", nil]; } - return [[clazz alloc] initWithElement:_element templateBuilder:_b]; + else { + assocs = [[NSMutableDictionary alloc] initWithObjects:&_condition + forKeys:&key count:1]; + } + children = [[NSArray alloc] initWithObjects:&_element count:1]; + element = [[WOConditionalClass alloc] initWithName:nil + associations:assocs + contentElements:children]; + [children release]; + [_element release]; + [assocs release]; + return element; +} + +- (WOElement *)wrapElements:(NSArray *)_sub inElementOfClass:(Class)_class { + WOElement *element; + + if (_sub == nil) + return nil; + + element = [[_class alloc] initWithName:nil + associations:nil + contentElements:_sub]; + return element; } -@end /* SxTagClassElemBuilder */ +- (WOElement *)wrapChildrenOfElement:(id)_tag + inElementOfClass:(Class)_class + templateBuilder:(id)_b +{ + NSArray *children; + + children = [_tag hasChildNodes] + ? [_b buildNodes:[_tag childNodes] templateBuilder:_b] + : nil; + + return [self wrapElements:children inElementOfClass:_class]; +} + +@end /* WOxElemBuilder */