]> 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 ca5d725c4fce6e5995c3c327d38e068c6dd0fa32..af29e83fd64e01c5e5bcc3836f6d3ab418083268 100644 (file)
@@ -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.
 */
 #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 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<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];
+}
 
-- (Class)classForElement:(id<DOMElement>)_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<DOMElement>)_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<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 */