]> err.no Git - sope/blobdiff - sope-appserver/NGObjWeb/Templates/WOxElemBuilder.m
fixed some NGMail framework build issue
[sope] / sope-appserver / NGObjWeb / Templates / WOxElemBuilder.m
index b053245015e7366a8a964da44824ebb2a5670f4f..af29e83fd64e01c5e5bcc3836f6d3ab418083268 100644 (file)
 #include <NGObjWeb/WOElement.h>
 #include <NGObjWeb/WOAssociation.h>
 #include <NGObjWeb/WOComponentScript.h>
+#include <NGObjWeb/WODynamicElement.h>
 #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;
 
 @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 NGLogger     *logger          = nil;
+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;
@@ -136,6 +142,7 @@ static NGLogger     *logger          = nil;
   if (logAssocCreation)
     [logger logWithFormat:@"association creation is logged!"];
 
+  // TODO: improve extensibility of this (remember WOWrapperTemplateBuilder)
   defaultAssocMap = [[ud dictionaryForKey:@"WOxAssociationClassMapping"] copy];
   if (defaultAssocMap == nil)
     [logger warnWithFormat:
@@ -143,6 +150,13 @@ static NGLogger     *logger          = nil;
   
   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 {
@@ -452,7 +466,7 @@ static NGLogger     *logger          = nil;
   
   self->nsToAssoc = [[NSMutableDictionary alloc] initWithCapacity:8];
   e = [defaultAssocMap keyEnumerator];
-  while ((ns = [e nextObject])) {
+  while ((ns = [e nextObject]) != nil) {
     NSString *className;
     Class    clazz;
     
@@ -481,7 +495,7 @@ static NGLogger     *logger          = nil;
   
   [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;
   
@@ -633,7 +647,134 @@ static NGLogger     *logger          = nil;
 
 - (void)reset {
   [self->subcomponentInfos removeAllObjects];
-  ASSIGN(self->script, (id)nil);
+  [self->script release]; self->script = nil;
+}
+
+/* support methods for subclasses */
+
+- (id<DOMElement>)lookupUniqueTag:(NSString *)_name
+  inElement:(id<DOMElement>)_elem
+{
+  id<DOMNodeList> 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];
+}
+
+- (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 *)elementForElementsAndStrings:(NSArray *)_elements {
+  /* Note: returns a retained element! */
+  NSMutableArray *ma;
+  WOElement *element;
+  unsigned  i, count;
+  
+  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];
+  }
+  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;
+}
+
+- (WOElement *)wrapChildrenOfElement:(id<DOMElement>)_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 */