2 Copyright (C) 2000-2004 SKYRIX Software AG
4 This file is part of OpenGroupware.org.
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
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.
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
23 #include <SxComponents/SxComponentRegistry.h>
24 #include <SxComponents/SxComponentMethodSignature.h>
27 @class NGXmlRpcClient;
29 @interface SxXmlRpcRegBackend : NSObject < SxComponentRegistryBackend >
31 NGXmlRpcClient *registryServer;
36 #include "SxXmlRpcComponent.h"
37 #import <NGXmlRpc/NGXmlRpcClient.h>
39 @interface NSObject(AsUrl)
43 @implementation SxXmlRpcRegBackend
46 static BOOL didInit = NO;
47 NSUserDefaults *ud = [NSUserDefaults standardUserDefaults];
53 defs = [NSDictionary dictionaryWithObjectsAndKeys:
54 @"http://127.0.0.1:14042/RPC2",
55 @"SxComponentRegistryURL",
57 [ud registerDefaults:defs];
60 + (NSURL *)defaultRegistryURL {
63 s = [[NSUserDefaults standardUserDefaults]
64 stringForKey:@"SxComponentRegistryURL"];
67 return [NSURL URLWithString:s];
70 - (id)initWithURL:(NSURL *)_url {
71 _url = [_url asNSURL];
76 self->registryServer = [[NGXmlRpcClient alloc] initWithURL:_url];
77 if (self->registryServer == nil) {
84 return [self initWithURL:[[self class] defaultRegistryURL]];
88 [self->registryServer release];
94 - (BOOL)registry:(id)_registry canHandleNamespace:(NSString *)_prefix {
95 NSArray *supportedComponents = nil;
97 supportedComponents = [self registry:_registry listComponents:@""];
99 [self logWithFormat:@"supported components : %@", supportedComponents];
101 return [supportedComponents containsObject:_prefix];
104 - (BOOL)canHandleComponent:(SxComponent *)_component {
105 if (_component == nil) return NO;
106 if (![_component isKindOfClass:[SxXmlRpcComponent class]]) return NO;
110 - (NSArray *)registry:(id)_registry listComponents:(NSString *)_prefix {
113 result = [self->registryServer
114 invokeMethodNamed:@"active.registry.getComponents"];
117 if ([result isKindOfClass:[NSException class]]) {
119 [self logWithFormat:@"%s: component list failed: %@",
120 __PRETTY_FUNCTION__, result];
123 else if ([result isKindOfClass:[NSDictionary class]]) {
125 [self logWithFormat:@"%s: component list failed (got a dict?): %@",
126 __PRETTY_FUNCTION__, result];
129 if (![result respondsToSelector:@selector(objectEnumerator)]) {
130 [self logWithFormat:@"%s: got invalid result: %@", __PRETTY_FUNCTION__,
135 if ([_prefix length] == 0)
138 /* limit search ... */
145 e = [result objectEnumerator];
146 while ((k = [e nextObject])) {
147 if ([k hasPrefix:_prefix]) {
149 ma = [NSMutableArray arrayWithCapacity:32];
159 - (id)processInvalidResultType:(id)_result method:(NSString *)_name {
163 ui = [NSDictionary dictionaryWithObjectsAndKeys:
164 _result, @"resultObject",
165 NSStringFromClass([_result class]), @"resultClassName",
168 exc = [NSException exceptionWithName:@"SxRegistryIntrospectionError"
169 reason:[_name stringByAppendingString:@" failed ..."]
172 [self logWithFormat:@"WARNING(%@): got invalid result type !", _name];
176 - (BOOL)isXmlRpcFault:(id)_object {
177 if ([_object isKindOfClass:[NSException class]])
182 - (NSArray *)registry:(id)_registry listMethods:(NSString *)_cname {
185 res = [self->registryServer
186 invokeMethodNamed:@"active.registry.listComponentMethods"
187 parameters:[NSArray arrayWithObject:_cname]];
189 if (res == nil) return nil;
191 if ([self isXmlRpcFault:res])
193 else if (![res isKindOfClass:[NSArray class]])
194 res = [self processInvalidResultType:res method:@"listMethods"];
199 - (NSArray *)registry:(id)_registry methodSignature:(NSString *)_cname
200 method:(NSString *)_methods
203 NSMutableArray *result;
204 NSEnumerator *sigEnum;
207 sigs = [self->registryServer
208 invokeMethodNamed:@"active.registry.componentMethodSignatures"
209 parameters:[NSArray arrayWithObjects:_cname,_methods,nil]];
211 if ([sigs isKindOfClass:[NSException class]])
213 else if (![sigs isKindOfClass:[NSArray class]])
214 return [self processInvalidResultType:sigs method:
215 @"componentMethodSignatures"];
217 sigEnum = [sigs objectEnumerator];
218 result = [NSMutableArray arrayWithCapacity:[sigs count]];
220 while((sigElem = [sigEnum nextObject])) {
221 SxComponentMethodSignature *sig;
223 sig = [SxComponentMethodSignature signatureWithXmlRpcTypes:sigElem];
224 [result addObject:sig];
229 - (NSString *)registry:(id)_registry
230 methodHelp:(NSString *)_cname
231 method:(NSString *)_methods
233 return [self->registryServer
234 invokeMethodNamed:@"active.registry.componentMethodHelp"
235 parameters:[NSArray arrayWithObjects:_cname,_methods,nil]];
238 - (SxComponent *)registry:(id)_registry getComponent:(NSString *)_cname {
240 SxXmlRpcComponent *xc;
244 res = [self->registryServer
245 invokeMethodNamed:@"active.registry.getComponentAndNamespace"
246 parameters:[NSArray arrayWithObject:_cname]];
248 if (res == nil) return nil;
250 if ([self isXmlRpcFault:res]) {
252 NSLog(@"%s: component lookup failed: %@", __PRETTY_FUNCTION__, res);
256 if (![res isKindOfClass:[NSDictionary class]]) {
257 NSLog(@"%s: got invalid result: %@", __PRETTY_FUNCTION__, res);
261 s = [NSString stringWithFormat:@"http://%@:%d%@",
262 [res objectForKey:@"host"],
263 [[res objectForKey:@"port"] intValue],
264 [res objectForKey:@"uri"]];
266 if ((url = [NSURL URLWithString:s]) == nil) {
267 [self logWithFormat:@"didn't get a valid URL: '%@'", s];
272 [[SxXmlRpcComponent alloc] initWithName:_cname
273 namespace:[res objectForKey:@"namespace"]
276 return AUTORELEASE(xc);
281 - (BOOL)removeComponent:(NSString *)_component {
284 res = [self->registryServer
285 call:@"active.registry.removeComponent", _component, nil];
286 return [res boolValue];
289 - (BOOL)addComponent:(NSString *)_component url:(id)_url {
292 url = [_url asNSURL];
294 return [[self->registryServer
295 call:@"active.registry.setComponent",
296 _component, [url path], [url host], [url port], nil]
300 - (BOOL)registerComponent:(SxComponent *)_component {
301 SxXmlRpcComponent *xc;
303 NSAssert([_component isKindOfClass:[SxXmlRpcComponent class]],
304 @"passed invalid component ...");
305 xc = (SxXmlRpcComponent *)_component;
310 - (BOOL)unregisterComponent:(SxComponent *)_component {
311 SxXmlRpcComponent *xc;
313 NSAssert([_component isKindOfClass:[SxXmlRpcComponent class]],
314 @"passed invalid component ...");
315 xc = (SxXmlRpcComponent *)_component;
322 - (NSString *)description {
323 return [NSString stringWithFormat:
324 @"<0x%08X[%@]: server=%@>",
325 self, NSStringFromClass([self class]),
326 self->registryServer];
329 @end /* SxXmlRpcRegBackend */
331 @implementation NSURL(AsUrl)
337 @end /* NSURL(AsUrl) */
339 @implementation NSObject(AsUrl)
343 s = [self stringValue];
344 if ([s length] == 0) return nil;
345 return [NSURL URLWithString:s];
348 @end /* NSURL(AsUrl) */