]> err.no Git - sope/blob - sope-appserver/SxComponents/SxXmlRpcRegBackend.m
added svn:keywords and svn:ignore where appropriate. removed CVS artifacts.
[sope] / sope-appserver / SxComponents / SxXmlRpcRegBackend.m
1 /*
2   Copyright (C) 2000-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 <SxComponents/SxComponentRegistry.h>
24 #include <SxComponents/SxComponentMethodSignature.h>
25 #include "common.h"
26
27 @class NGXmlRpcClient;
28
29 @interface SxXmlRpcRegBackend : NSObject < SxComponentRegistryBackend >
30 {
31   NGXmlRpcClient *registryServer;
32 }
33
34 @end
35
36 #include "SxXmlRpcComponent.h"
37 #import <NGXmlRpc/NGXmlRpcClient.h>
38
39 @interface NSObject(AsUrl)
40 - (NSURL *)asNSURL;
41 @end
42
43 @implementation SxXmlRpcRegBackend
44
45 + (void)initialize {
46   static BOOL didInit = NO;
47   NSUserDefaults *ud = [NSUserDefaults standardUserDefaults];
48   NSDictionary   *defs;
49   
50   if (didInit) return;
51   didInit = YES;
52     
53   defs = [NSDictionary dictionaryWithObjectsAndKeys:
54                          @"http://127.0.0.1:14042/RPC2", 
55                          @"SxComponentRegistryURL",
56                        nil];
57   [ud registerDefaults:defs];
58 }
59
60 + (NSURL *)defaultRegistryURL {
61   NSString *s;
62   
63   s = [[NSUserDefaults standardUserDefaults]
64                        stringForKey:@"SxComponentRegistryURL"];
65   if ([s length] == 0)
66     return nil;
67   return [NSURL URLWithString:s];
68 }
69
70 - (id)initWithURL:(NSURL *)_url {
71   _url = [_url asNSURL];
72   if (_url == nil) {
73     [self release];
74     return nil;
75   }
76   self->registryServer = [[NGXmlRpcClient alloc] initWithURL:_url];
77   if (self->registryServer == nil) {
78     [self release];
79     return nil;
80   }
81   return self;
82 }
83 - (id)init {
84   return [self initWithURL:[[self class] defaultRegistryURL]];
85 }
86
87 - (void)dealloc {
88   [self->registryServer release];
89   [super dealloc];
90 }
91
92 /* operations */
93
94 - (BOOL)registry:(id)_registry canHandleNamespace:(NSString *)_prefix {
95   NSArray *supportedComponents = nil;
96   
97   supportedComponents = [self registry:_registry listComponents:@""];
98 #if 0
99   [self logWithFormat:@"supported components : %@", supportedComponents];
100 #endif
101   return [supportedComponents containsObject:_prefix];
102 }
103
104 - (BOOL)canHandleComponent:(SxComponent *)_component {
105   if (_component == nil) return NO;
106   if (![_component isKindOfClass:[SxXmlRpcComponent class]]) return NO;
107   return YES;
108 }
109
110 - (NSArray *)registry:(id)_registry listComponents:(NSString *)_prefix {
111   NSArray *result;
112   
113   result = [self->registryServer
114                 invokeMethodNamed:@"active.registry.getComponents"];
115   if (result == nil)
116     return nil;
117   if ([result isKindOfClass:[NSException class]]) {
118     /* call failed */
119     [self logWithFormat:@"%s: component list failed: %@",
120             __PRETTY_FUNCTION__, result];
121     return nil;
122   }
123   else if ([result isKindOfClass:[NSDictionary class]]) {
124     /* call failed */
125     [self logWithFormat:@"%s: component list failed (got a dict?): %@",
126             __PRETTY_FUNCTION__, result];
127     return nil;
128   }
129   if (![result respondsToSelector:@selector(objectEnumerator)]) {
130     [self logWithFormat:@"%s: got invalid result: %@", __PRETTY_FUNCTION__,
131             result];
132     return nil;
133   }
134   
135   if ([_prefix length] == 0)
136     return result;
137   
138   /* limit search ... */
139   {
140     NSEnumerator *e;
141     NSString *k;
142     NSMutableArray *ma;
143
144     ma = nil;
145     e = [result objectEnumerator];
146     while ((k = [e nextObject])) {
147       if ([k hasPrefix:_prefix]) {
148         if (ma == nil)
149           ma = [NSMutableArray arrayWithCapacity:32];
150         [ma addObject:k];
151       }
152     }
153     result = ma;
154   }
155   
156   return result;
157 }
158
159 - (id)processInvalidResultType:(id)_result method:(NSString *)_name {
160   NSException  *exc;
161   NSDictionary *ui;
162   
163   ui = [NSDictionary dictionaryWithObjectsAndKeys:
164                        _result,                            @"resultObject",
165                        NSStringFromClass([_result class]), @"resultClassName",
166                        nil];
167   
168   exc = [NSException exceptionWithName:@"SxRegistryIntrospectionError"
169                      reason:[_name stringByAppendingString:@" failed ..."]
170                      userInfo:ui];
171   
172   [self logWithFormat:@"WARNING(%@): got invalid result type !", _name];
173   return exc;
174 }
175
176 - (BOOL)isXmlRpcFault:(id)_object {
177   if ([_object isKindOfClass:[NSException class]])
178     return YES;
179   return NO;
180 }
181
182 - (NSArray *)registry:(id)_registry listMethods:(NSString *)_cname {
183   NSArray *res;
184   
185   res = [self->registryServer
186              invokeMethodNamed:@"active.registry.listComponentMethods"
187              parameters:[NSArray arrayWithObject:_cname]];
188   
189   if (res == nil) return nil;
190
191   if ([self isXmlRpcFault:res])
192     return res;
193   else if (![res isKindOfClass:[NSArray class]])
194     res = [self processInvalidResultType:res method:@"listMethods"];
195   
196   return res;
197 }
198
199 - (NSArray *)registry:(id)_registry methodSignature:(NSString *)_cname
200   method:(NSString *)_methods
201 {
202   NSArray *sigs;
203   NSMutableArray *result;
204   NSEnumerator *sigEnum;
205   NSArray      *sigElem;
206
207   sigs =  [self->registryServer
208                invokeMethodNamed:@"active.registry.componentMethodSignatures"
209                parameters:[NSArray arrayWithObjects:_cname,_methods,nil]];
210   
211   if ([sigs isKindOfClass:[NSException class]])
212     return sigs;
213   else if (![sigs isKindOfClass:[NSArray class]])
214     return [self processInvalidResultType:sigs method:
215                  @"componentMethodSignatures"];
216   
217   sigEnum = [sigs objectEnumerator];
218   result = [NSMutableArray arrayWithCapacity:[sigs count]];
219   
220   while((sigElem = [sigEnum nextObject])) {
221     SxComponentMethodSignature *sig;
222
223     sig = [SxComponentMethodSignature signatureWithXmlRpcTypes:sigElem];
224     [result addObject:sig];
225   }
226   return result;
227 }
228
229 - (NSString *)registry:(id)_registry
230   methodHelp:(NSString *)_cname
231   method:(NSString *)_methods
232 {
233   return [self->registryServer
234               invokeMethodNamed:@"active.registry.componentMethodHelp"
235               parameters:[NSArray arrayWithObjects:_cname,_methods,nil]];
236 }
237
238 - (SxComponent *)registry:(id)_registry getComponent:(NSString *)_cname {
239   NSDictionary      *res;
240   SxXmlRpcComponent *xc;
241   NSURL    *url;
242   NSString *s;
243   
244   res = [self->registryServer
245              invokeMethodNamed:@"active.registry.getComponentAndNamespace"
246              parameters:[NSArray arrayWithObject:_cname]];
247   
248   if (res == nil) return nil;
249   
250   if ([self isXmlRpcFault:res]) {
251     /* call failed */
252     NSLog(@"%s: component lookup failed: %@", __PRETTY_FUNCTION__, res);
253     return nil;
254   }
255   
256   if (![res isKindOfClass:[NSDictionary class]]) {
257     NSLog(@"%s: got invalid result: %@", __PRETTY_FUNCTION__, res);
258     return nil;
259   }
260
261   s = [NSString stringWithFormat:@"http://%@:%d%@",
262                   [res  objectForKey:@"host"],
263                   [[res objectForKey:@"port"] intValue],
264                   [res  objectForKey:@"uri"]];
265
266   if ((url = [NSURL URLWithString:s]) == nil) {
267     [self logWithFormat:@"didn't get a valid URL: '%@'", s];
268     return nil;
269   }
270   
271   xc =
272     [[SxXmlRpcComponent alloc] initWithName:_cname
273                                namespace:[res objectForKey:@"namespace"]
274                                registry:_registry
275                                url:url];
276   return AUTORELEASE(xc);
277 }
278
279
280
281 - (BOOL)removeComponent:(NSString *)_component {
282   id res;
283   
284   res = [self->registryServer
285              call:@"active.registry.removeComponent", _component, nil];
286   return [res boolValue];
287 }
288
289 - (BOOL)addComponent:(NSString *)_component url:(id)_url {
290   NSURL *url;
291
292   url = [_url asNSURL];
293   
294   return [[self->registryServer
295                call:@"active.registry.setComponent",
296                  _component, [url path], [url host], [url port], nil]
297                boolValue];
298 }
299
300 - (BOOL)registerComponent:(SxComponent *)_component {
301   SxXmlRpcComponent *xc;
302   
303   NSAssert([_component isKindOfClass:[SxXmlRpcComponent class]],
304            @"passed invalid component ...");
305   xc = (SxXmlRpcComponent *)_component;
306
307   return NO;
308 }
309
310 - (BOOL)unregisterComponent:(SxComponent *)_component {
311   SxXmlRpcComponent *xc;
312   
313   NSAssert([_component isKindOfClass:[SxXmlRpcComponent class]],
314            @"passed invalid component ...");
315   xc = (SxXmlRpcComponent *)_component;
316
317   return NO;
318 }
319
320 /* description */
321
322 - (NSString *)description {
323   return [NSString stringWithFormat:
324                      @"<0x%08X[%@]: server=%@>",
325                      self, NSStringFromClass([self class]),
326                      self->registryServer];
327 }
328
329 @end /* SxXmlRpcRegBackend */
330
331 @implementation NSURL(AsUrl)
332
333 - (NSURL *)asNSURL {
334   return self;
335 }
336
337 @end /* NSURL(AsUrl) */
338
339 @implementation NSObject(AsUrl)
340
341 - (NSURL *)asNSURL {
342   NSString *s;
343   s = [self stringValue];
344   if ([s length] == 0) return nil;
345   return [NSURL URLWithString:s];
346 }
347
348 @end /* NSURL(AsUrl) */