]> err.no Git - sope/blobdiff - sope-appserver/NGObjWeb/WOApplication.m
minor improvement to WOHttpAdaptor, bumped framework revisions
[sope] / sope-appserver / NGObjWeb / WOApplication.m
index afc3fd0be740196f87509fd37ca426a263c8ae4a..a79b58717900cf1707391d9b43ed17946974c167 100644 (file)
@@ -1,20 +1,21 @@
 /*
-  Copyright (C) 2000-2004 SKYRIX Software AG
+  Copyright (C) 2000-2005 SKYRIX Software AG
+  Copyright (C) 2006      Helge Hess
 
-  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/WOStatisticsStore.h>
 #include <NGObjWeb/WODynamicElement.h>
 #include <NGObjWeb/WOTemplate.h>
-#import <EOControl/EOControl.h>
+#include <EOControl/EOControl.h>
 #include "common.h"
 #include <time.h>
 
+#if GNU_RUNTIME
+#  include <objc/sarray.h>
+#endif
+
 @interface WOApplication(PrivateMethods)
 + (id)logger;
 - (id)_loadComponentDefinitionWithName:(NSString *)_name
@@ -57,6 +62,12 @@ static NSString *rapidTurnAroundPath = nil;
 
 @implementation WOApplication
 
+#if 1 // TODO: why is that? why isn't that set by a default?
+static NSString *defaultCompRqHandlerClassName = @"OWViewRequestHandler";
+#else
+static NSString *defaultCompRqHandlerClassName = @"WOComponentRequestHandler";
+#endif
+
 + (int)version {
   return [super version] + 5 /* v6 */;
 }
@@ -182,7 +193,7 @@ static NSString *rapidTurnAroundPath = nil;
       
       pi  = [NSProcessInfo processInfo];
       env = [pi environment];
-      if ([env objectForKey:@"GNUSTEP_SYSTEM_ROOT"] != nil) {
+      if ([[env objectForKey:@"GNUSTEP_SYSTEM_ROOT"] isNotNull]) {
        isFlattened = [[[env objectForKey:@"GNUSTEP_FLATTENED"]
                              lowercaseString] isEqualToString:@"yes"];
       }
@@ -238,7 +249,7 @@ static NSString *rapidTurnAroundPath = nil;
 - (id)initWithName:(NSString *)_name {
   [WOApplication _initializeWOApp];
   
-  if ((self = [super init])) {
+  if ((self = [super init]) != nil) {
     NSUserDefaults   *ud;
     WORequestHandler *rh;
     NSString *rk;
@@ -265,25 +276,26 @@ static NSString *rapidTurnAroundPath = nil;
     self->requestHandlerRegistry =
       NSCreateMapTable(NSObjectMapKeyCallBacks, NSObjectMapValueCallBacks, 8);
     
-    rk = [WOApplication componentRequestHandlerKey];
-#if 1
-    rh = [[NSClassFromString(@"OWViewRequestHandler") alloc] init];
-#else
-    rh = [[NSClassFromString(@"WOComponentRequestHandler") alloc] init];
-#endif
-    if ([rk length] > 0 && (rh != nil))
+    if ((rk = [WOApplication componentRequestHandlerKey]) == nil) {
+      [self logWithFormat:
+             @"WARNING: no component request handler key is specified, "
+             @"this probably means that share/ngobjweb/Defaults.plist "
+             @"could not get loaded (permissions?)"];
+    }
+    rh = [[NSClassFromString(defaultCompRqHandlerClassName) alloc] init];
+    if ([rk isNotEmpty] && [rh isNotNull])
       [self registerRequestHandler:rh forKey:rk];
     [rh release]; rh = nil;
     
     rk = [WOApplication directActionRequestHandlerKey];
     rh = [[NSClassFromString(@"WODirectActionRequestHandler") alloc] init];
-    if ([rk length] > 0 && rh != nil)
+    if ([rk isNotEmpty] && [rh isNotNull])
       [self registerRequestHandler:rh forKey:rk];
     [rh release]; rh = nil;
     
     if ((rh = [[NSClassFromString(@"WOResourceRequestHandler") alloc] init])) {
       rk = [WOApplication resourceRequestHandlerKey];
-      if ([rk length] > 0)
+      if ([rk isNotEmpty])
         [self registerRequestHandler:rh forKey:rk];
       [self registerRequestHandler:rh forKey:@"WebServerResources"];
 #ifdef __APPLE__
@@ -491,7 +503,7 @@ static NSString *rapidTurnAroundPath = nil;
   WOSession *sn;
 
   sn = [self createSessionForRequest:[_ctx request]];
-  [_ctx setSession:sn];
+  [_ctx setNewSession:sn];
   
   if ([sn respondsToSelector:@selector(prepare)]) {
 #if DEBUG
@@ -515,7 +527,7 @@ static NSString *rapidTurnAroundPath = nil;
   
   /* first look into form values */
   if ((sessionId = [_request formValueForKey:WORequestValueSessionID])!=nil) {
-    if ([sessionId length] > 0)
+    if ([sessionId isNotEmpty])
       return sessionId;
   }
   
@@ -526,12 +538,12 @@ static NSString *rapidTurnAroundPath = nil;
       
       e = [(id)sessionId objectEnumerator];
       while ((sessionId = [e nextObject]) != nil) {
-        if ([sessionId length] > 0 && ![sessionId isEqual:@"nil"])
+        if ([sessionId isNotEmpty] && ![sessionId isEqual:@"nil"])
           return sessionId;
       }
     }
     else {
-      if ([sessionId length] > 0 && ![sessionId isEqual:@"nil"])
+      if ([sessionId isNotEmpty] && ![sessionId isEqual:@"nil"])
         return sessionId;
     }
   }
@@ -546,14 +558,14 @@ static NSString *rapidTurnAroundPath = nil;
   unsigned char buf[20];
   
   sessionCount++;
-  sprintf(buf, "%04X%04X%02X%08X",
+  sprintf((char *)buf, "%04X%04X%02X%08X",
           [[self number] intValue], getpid(), sessionCount, 
           (unsigned int)time(NULL));
-  wosid = [NSString stringWithCString:buf];
+  wosid = [NSString stringWithCString:(char *)buf];
   return wosid;
 }
 
-- (WOSession *)createSessionForRequest:(WORequest *)_request {
+- (id)createSessionForRequest:(WORequest *)_request {
   if ([self respondsToSelector:@selector(createSession)]) {
     /* call deprecated method */
     [self warnWithFormat:@"calling deprecated -createSession .."];
@@ -569,9 +581,7 @@ static NSString *rapidTurnAroundPath = nil;
   }
 }
 
-- (WOSession *)restoreSessionWithID:(NSString *)_sid
-  inContext:(WOContext *)_ctx
-{
+- (id)restoreSessionWithID:(NSString *)_sid inContext:(WOContext *)_ctx {
   WOSession *session;
   
   *(&session) = nil;
@@ -590,7 +600,7 @@ static NSString *rapidTurnAroundPath = nil;
     }
     else {
       session = [store restoreSessionWithID:_sid request:[_ctx request]];
-      if (session) {
+      if ([session isNotNull]) {
         [_ctx setSession:session];
         [session _awakeWithContext:_ctx];
       }
@@ -742,7 +752,7 @@ static NSString *rapidTurnAroundPath = nil;
   }
 }
 
-- (WOSession *)session {
+- (id)session {
   return [[self context] session];
 }
 
@@ -792,6 +802,8 @@ static NSString *rapidTurnAroundPath = nil;
     return [self handleSessionRestorationError];
   }
   
+  // TODO: is it correct to return nil?
+  // TODO: we should return a page saying sorry with a cookie + redirect
   [self errorWithFormat:@"could not restore session for context %@", _ctx];
   return nil;
 }
@@ -811,23 +823,38 @@ static NSString *rapidTurnAroundPath = nil;
 
 /* resources */
 
+- (void)_setupDefaultResourceManager {
+  NSUserDefaults *ud;
+  Class    rmClass;
+  NSString *p;
+  
+  ud = [NSUserDefaults standardUserDefaults];
+  p  = [ud stringForKey:@"WODefaultResourceManager"];
+  rmClass = [p isNotEmpty]
+    ? NSClassFromString(p)
+    : [WOResourceManager class];
+  
+  if (rmClass == Nil) {
+    [self errorWithFormat:
+            @"failed to locate class of resource manager: '%@'", p];
+    return;
+  }
+  
+  if ([rmClass instancesRespondToSelector:@selector(initWithPath:)])
+    self->resourceManager = [[rmClass alloc] init];
+  else {
+    self->resourceManager = 
+      [(WOResourceManager *)[rmClass alloc] initWithPath:[self path]];
+  }
+}
+
 - (void)setResourceManager:(WOResourceManager *)_manager {
   ASSIGN(self->resourceManager, _manager);
 }
 - (WOResourceManager *)resourceManager {
-  if (self->resourceManager == nil) {
-    NSString *p;
-
-#if 0 && DEBUG
-    if ([(p = [self path]) length] > 0)
-      [self debugWithFormat:@"setup WOResourceManager at path '%@' ...", p];
-#else
-    p = [self path];
-#endif
-    
-    self->resourceManager = 
-      [(WOResourceManager *)[WOResourceManager alloc] initWithPath:p];
-  }
+  if (self->resourceManager == nil)
+    [self _setupDefaultResourceManager];
+  
   return self->resourceManager;
 }
 
@@ -863,6 +890,17 @@ static NSString *rapidTurnAroundPath = nil;
 - (void)awake {
 }
 - (void)sleep {
+#if DEBUG && PRINT_NSSTRING_STATISTICS
+  if ([NSString respondsToSelector:@selector(printStatistics)])
+    [NSString printStatistics];
+#endif
+  
+#if DEBUG && PRINT_OBJC_STATISTICS
+extern int __objc_selector_max_index;
+  printf("nbuckets=%i, nindices=%i, narrays=%i, idxsize=%i\n",
+nbuckets, nindices, narrays, idxsize);
+  printf("maxsel=%i\n", __objc_selector_max_index);
+#endif
 }
 
 /* responder */
@@ -873,7 +911,7 @@ static NSString *rapidTurnAroundPath = nil;
   else {
     WOComponent *page;
     
-    if ((page = [_ctx page])) {
+    if ((page = [_ctx page]) != nil) {
       WOContext_enterComponent(_ctx, page, nil);
       [page takeValuesFromRequest:_req inContext:_ctx];
       WOContext_leaveComponent(_ctx, page);
@@ -997,7 +1035,7 @@ static NSString *rapidTurnAroundPath = nil;
   return self->permanentPageCacheSize;
 }
 
-- (WOComponent *)pageWithName:(NSString *)_name {
+- (id)pageWithName:(NSString *)_name {
   // deprecated in WO4
   return [self pageWithName:_name inContext:[self context]];
 }
@@ -1024,17 +1062,24 @@ static NSString *rapidTurnAroundPath = nil;
   start = [self memoryStatistics];
 #endif
   
-  pool = [[NSAutoreleasePool alloc] init];
+  pool      = [[NSAutoreleasePool alloc] init];
   
-  languages = [_ctx hasSession]
-    ? [(WOSession *)[_ctx session] languages]
-    : [[_ctx request] browserLanguages];
+  languages = [_ctx resourceLookupLanguages];
 
   if ((rm = [[_ctx component] resourceManager]) == nil)
     rm = [self resourceManager];
   
-  page = [rm pageWithName:(_name != nil ? _name : @"Main")
-             languages:languages];
+  /*  TODO:
+   *  the following ignores the fact that the passed context may be different
+   *  from that of WOApplication. During the course of template instantiation
+   *  WOApplication's current context gets attached to page which is definitely
+   *  wrong. We workaround this problem by using the private API of WOComponent
+   *  to explicitly set it. However all accompanied methods should be
+   *  extended to pass the correct context where needed.
+   */
+  page      = [rm pageWithName:(_name != nil ? _name : @"Main")
+                  languages:languages];
+  [page _setContext:_ctx];
   [page ensureAwakeInContext:_ctx];
   
   page = [page retain];
@@ -1057,10 +1102,10 @@ static NSString *rapidTurnAroundPath = nil;
   
   return [page autorelease];
 }
-- (WOComponent *)pageWithName:(NSString *)_name inContext:(WOContext *)_ctx {
+- (id)pageWithName:(NSString *)_name inContext:(WOContext *)_ctx {
   return [self _pageWithName:_name inContext:_ctx];
 }
-- (WOComponent *)pageWithName:(NSString *)_name forRequest:(WORequest *)_req {
+- (id)pageWithName:(NSString *)_name forRequest:(WORequest *)_req {
   WOResourceManager *rm;
 
   if ((rm = [self resourceManager]) == nil)
@@ -1159,7 +1204,7 @@ static NSString *rapidTurnAroundPath = nil;
     
     [r setHeader:@"text/html" forKey:@"content-type"];
     [r setHeader:@"no-cache" forKey:@"cache-control"];
-    if(rapidTurnAroundPath != nil) {
+    if (rapidTurnAroundPath != nil) {
         NSURL *templateURL;
         
         templateURL = [[_exc userInfo] objectForKey:@"templateURL"];
@@ -1243,7 +1288,8 @@ static NSString *rapidTurnAroundPath = nil;
   static BOOL  lookedUpForEOEditingContextClass = NO;
   
   if (!lookedUpForEOEditingContextClass) {
-    eoEditingContextClass = NSClassFromString(@"EOEditingContext");
+    if ((eoEditingContextClass = NSClassFromString(@"EOEditingContext")) ==nil)
+      eoEditingContextClass = NSClassFromString(@"NSManagedObjectContext");
     lookedUpForEOEditingContextClass = YES;
   }
   return eoEditingContextClass;