]> err.no Git - sope/blob - sope-appserver/NGObjWeb/SoObjects/SoApplication.m
fixed OGo bug #888
[sope] / sope-appserver / NGObjWeb / SoObjects / SoApplication.m
1 /*
2   Copyright (C) 2002-2004 SKYRIX Software AG
3
4   This file is part of OpenGroupware.org.
5
6   OGo is free software; you can redistribute it and/or modify it under
7   the terms of the GNU Lesser General Public License as published by the
8   Free Software Foundation; either version 2, or (at your option) any
9   later version.
10
11   OGo is distributed in the hope that it will be useful, but WITHOUT ANY
12   WARRANTY; without even the implied warranty of MERCHANTABILITY or
13   FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
14   License for more details.
15
16   You should have received a copy of the GNU Lesser General Public
17   License along with OGo; see the file COPYING.  If not, write to the
18   Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA
19   02111-1307, USA.
20 */
21 // $Id$
22
23 #include "SoApplication.h"
24 #include "SoClassRegistry.h"
25 #include "SoControlPanel.h"
26 #include "SoObject.h"
27 #include "SoObjectRequestHandler.h"
28 #include "SoProductRegistry.h"
29 #include "SoSecurityManager.h"
30 #include "SoApplication.h"
31 #include "SoObject+SoDAV.h"
32 #include <NGObjWeb/WORequest.h>
33 #include "common.h"
34
35 @implementation SoApplication
36
37 static BOOL debugLookup = NO;
38
39 - (BOOL)loadProducts:(id)_spec  {
40   if (_spec) {
41     // TODO: load specified products
42     [self logWithFormat:@"load products (not implemented): %@", _spec];
43     return NO;
44   }
45   else
46     [self->productRegistry loadAllProducts];
47   
48   return YES;
49 }
50
51 - (id)init {
52   if ((self = [super init])) {
53     NSUserDefaults *ud = [NSUserDefaults standardUserDefaults];
54     id tmp;
55     
56     debugLookup = [ud boolForKey:@"SoDebugKeyLookup"];
57     
58     /* setup global objects */
59     
60     self->securityManager = [[SoSecurityManager sharedSecurityManager] retain];
61     self->classRegistry   = [[SoClassRegistry sharedClassRegistry] retain];
62     self->productRegistry = [[SoProductRegistry sharedProductRegistry] retain];
63     
64     /* Object Publishing */
65     tmp = [[SoObjectRequestHandler alloc] init];
66     [self registerRequestHandler:tmp forKey:@"so"];
67     [self registerRequestHandler:tmp forKey:@"dav"];
68     [self registerRequestHandler:tmp forKey:@"RPC2"];
69     [self setDefaultRequestHandler:tmp];
70     [tmp release];
71     
72     /* load products */
73     if (![self loadProducts:[ud objectForKey:@"SoApplicationLoadProducts"]]) {
74       [self logWithFormat:@"failed to load the products ..."];
75       [self release];
76       return nil;
77     }
78     
79 #if LIB_FOUNDATION_LIBRARY
80     /* debugging */
81     if ([[ud objectForKey:@"EnableDoubleReleaseCheck"] boolValue])
82       [NSAutoreleasePool enableDoubleReleaseCheck:YES];
83 #endif
84   }
85   return self;
86 }
87
88 - (void)dealloc {
89   [self->securityManager release];
90   [self->classRegistry   release];
91   [self->productRegistry release];
92   [super dealloc];
93 }
94
95 /* accessors */
96
97 - (SoProductRegistry *)productRegistry {
98   return self->productRegistry;
99 }
100 - (SoClassRegistry *)classRegistry {
101   return self->classRegistry;
102 }
103 - (SoSecurityManager *)securityManager {
104   return self->securityManager;
105 }
106
107 /* application as the SoObject root */
108
109 - (id)rootObjectInContext:(id)_ctx {
110   return nil;
111 }
112
113 - (NSException *)validateName:(NSString *)_key inContext:(id)_ctx {
114   id root;
115   
116   if ([self hasName:_key inContext:_ctx])
117     return [super validateName:_key inContext:_ctx];
118   
119   root = [self rootObjectInContext:_ctx];
120   return (root != self) 
121     ? [root validateName:_key inContext:_ctx] 
122     : [super validateName:_key inContext:_ctx];
123 }
124
125 - (BOOL)hasName:(NSString *)_key inContext:(id)_ctx {
126   id root;
127   
128   if ([_key isEqualToString:@"ControlPanel"])
129     return YES;
130   
131   if ([[self registeredRequestHandlerKeys] containsObject:_key])
132     return YES;
133   
134   if ([super hasName:_key inContext:_ctx])
135     return YES;
136   
137   root = [self rootObjectInContext:_ctx];
138   if (root != self)
139     return [root hasName:_key inContext:_ctx];
140   
141   return NO;
142 }
143
144 - (id)controlPanel:(NSString *)_name inContext:(id)_ctx {
145   return [[[SoControlPanel alloc] init] autorelease];
146 }
147
148 - (BOOL)isApplicationNameLookup:(NSString *)_name inContext:(id)_ctx {
149   static NSString *WOApplicationSuffix = nil;
150   NSString *appName;
151
152   appName = [[(WOContext *)_ctx request] applicationName];
153   if ([_name isEqual:appName]) {
154     if (debugLookup) [self logWithFormat:@"  matched appname: %@", appName];
155     return YES;
156   }
157
158   if (WOApplicationSuffix == nil) {
159     NSUserDefaults *ud = [NSUserDefaults standardUserDefaults];
160     WOApplicationSuffix = [[ud stringForKey:@"WOApplicationSuffix"] copy];
161   }
162   appName = [appName stringByAppendingString:WOApplicationSuffix];
163   if ([_name isEqual:appName]) {
164     if (debugLookup) [self logWithFormat:@"  matched appname: %@", appName];
165     return YES;
166   }
167   
168   return NO;
169 }
170
171 - (id)lookupName:(NSString *)_name inContext:(id)_ctx acquire:(BOOL)_flag {
172   id v;
173   
174   if ([_name isEqualToString:@"ControlPanel"])
175     return [self controlPanel:_name inContext:_ctx];
176   
177   if ([[self registeredRequestHandlerKeys] containsObject:_name]) {
178     /* 
179       need to check registeredRequestHandlerKeys because requestHandlerForKey:
180       returns the default handler if the key could not be found ...
181     */
182     if ((v = [super requestHandlerForKey:_name]))
183       return v;
184   }
185   
186   if (debugLookup) [self logWithFormat:@"lookup name: %@", _name];
187   
188   if ((v = [super lookupName:_name inContext:_ctx acquire:NO]) == nil) {
189     id root;
190     
191     root = [self rootObjectInContext:_ctx];
192     if (debugLookup) [self logWithFormat:@"  lookup in root object: %@", v];
193     
194     if (root != self)
195       v = [root lookupName:_name inContext:_ctx acquire:_flag];
196     else if (debugLookup)
197       [self logWithFormat:@"  root is application object"];
198   }
199   
200   if (debugLookup) [self logWithFormat:@"  GOT: %@", v];
201   
202   /* 
203      hack to allow "/myapp/folder/", it is a hack because it also allows
204      /myapp/myapp/myapp/.../folder/ ...
205   */
206   if (v == nil && [self isApplicationNameLookup:_name inContext:_ctx])
207     v = self;
208   
209   return v;
210 }
211
212 - (NSArray *)toOneRelationshipKeys {
213   NSMutableSet *ma;
214   id root;
215   
216   ma = ((root = [super toOneRelationshipKeys]))
217     ? [[NSMutableSet alloc] initWithArray:root]
218     : [[NSMutableSet alloc] init];
219   
220   [ma addObjectsFromArray:[self registeredRequestHandlerKeys]];
221   [ma addObject:@"ControlPanel"];
222   
223   root = [self rootObjectInContext:[self context]];
224   if (root != nil && (root != self)) 
225     [ma addObjectsFromArray:[root toOneRelationshipKeys]];
226   
227   root = [ma allObjects];
228   [ma release];
229   return root;
230 }
231
232 /* WebDAV support for root objects */
233
234 - (id)davCreateObject:(NSString *)_name
235   properties:(NSDictionary *)_props
236   inContext:(id)_ctx
237 {
238   id root;
239
240   if ((root = [self rootObjectInContext:_ctx]) == nil)
241     return [super davCreateObject:_name properties:_props inContext:_ctx];
242   
243   return [root davCreateObject:_name properties:_props inContext:_ctx];
244 }
245
246 - (NSException *)davCreateCollection:(NSString *)_name inContext:(id)_ctx {
247   id root;
248
249   if ((root = [self rootObjectInContext:_ctx]) == nil)
250     return [super davCreateCollection:_name inContext:_ctx];
251   
252   //[self debugWithFormat:@"let root '%@' create collection '%@'", root,_name];
253   return [root davCreateCollection:_name inContext:_ctx];
254 }
255
256 @end /* SoApplication */