]> err.no Git - sope/blob - sope-appserver/NGObjWeb/SoObjects/SoObjCClass.m
added some WebDrive WebDAV properties
[sope] / sope-appserver / NGObjWeb / SoObjects / SoObjCClass.m
1 /*
2   Copyright (C) 2002-2005 SKYRIX Software AG
3
4   This file is part of SOPE.
5
6   SOPE 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   SOPE 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 SOPE; 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
22 #include "SoObjCClass.h"
23 #include "SoSelectorInvocation.h"
24 #include <NGExtensions/NGObjCRuntime.h>
25 #include <NGExtensions/NSString+Ext.h>
26 #include "common.h"
27
28 @implementation SoObjCClass
29
30 - (id)initWithSoSuperClass:(SoClass *)_soClass class:(Class)_clazz {
31   NSAssert(_clazz, @"missing ObjC class parameter !");
32   if ((self = [super initWithSoSuperClass:_soClass])) {
33     self->clazz = _clazz;
34   }
35   return self;
36 }
37 - (id)initWithSoSuperClass:(SoClass *)_soClass {
38   return [self initWithSoSuperClass:_soClass class:nil];
39 }
40
41 - (void)rescanClass {
42   NSMutableDictionary *prefixMap;
43   NSEnumerator *e;
44   NSString *methodName;
45   
46   prefixMap = [[NSMutableDictionary alloc] initWithCapacity:32];
47   
48   [self debugWithFormat:@"scanning ObjC class %@ for SoObject methods ...",
49           NSStringFromClass(self->clazz)];
50   e = [self->clazz methodNameEnumerator];
51   while ((methodName = [e nextObject])) {
52     SoSelectorInvocation *invocation;
53     NSString *methodPrefix;
54     NSRange  r;
55     unsigned len;
56     
57     if ((len = [methodName length]) < 6)
58       continue;
59     
60     r = [methodName rangeOfString:@"Action"];
61     if (r.length == 0) continue;
62     
63     /* eg: doItAction:abc: => doItAction */
64     methodPrefix = [methodName substringToIndex:(r.location + r.length)];
65     
66     if (len > (r.location + r.length)) {
67       /* something is beyond the xxxAction, *must* be followed by a colon */
68       if ([methodName characterAtIndex:(r.location + r.length)] != ':')
69         continue;
70     }
71     
72     [self debugWithFormat:@"  found an action: %@", methodName];
73     
74     if ((invocation = [prefixMap objectForKey:methodPrefix]) == nil) {
75       invocation = [[SoSelectorInvocation alloc] init];
76       [prefixMap setObject:invocation forKey:methodPrefix];
77       [invocation release];
78     }
79     [invocation addSelectorNamed:methodName];
80   }
81   
82   e = [prefixMap keyEnumerator];
83   while ((methodName = [e nextObject])) {
84     SoSelectorInvocation *inv;
85     NSString *slotName;
86     
87     slotName = [methodName hasSuffix:@"Action"]
88       ? [methodName substringToIndex:([methodName length] - 6)]
89       : methodName;
90     inv = [prefixMap objectForKey:methodName];
91     [self setValue:inv forSlot:slotName];
92   }
93 }
94
95 /* factory */
96
97 - (id)instantiateObject {
98   return [[[self->clazz alloc] init] autorelease];
99 }
100
101 - (NSClassDescription *)soClassDescription {
102   return [NSClassDescription classDescriptionForClass:self->clazz];
103 }
104
105 - (NSString *)className {
106   return NSStringFromClass(self->clazz);
107 }
108 - (Class)objcClass {
109   return self->clazz;
110 }
111
112 /* description */
113
114 - (NSString *)description {
115   NSMutableString *ms;
116   
117   ms = [NSMutableString stringWithCapacity:64];
118   [ms appendFormat:@"<0x%08X[%@]:", self,
119         NSStringFromClass((Class)*(void**)self)];
120   
121   if (self->soSuperClass)
122     [ms appendFormat:@" super=0x%08X", self->soSuperClass];
123   else
124     [ms appendString:@" root"];
125
126   if (self->clazz)
127     [ms appendFormat:@" objc=%@", NSStringFromClass(self->clazz)];
128   else
129     [ms appendString:@" <no-objc-class>"];
130   
131   if ([self->slots count] > 0) {
132     [ms appendFormat:@" slots=%@", 
133           [[self->slots allKeys] componentsJoinedByString:@","]];
134   }
135   
136   [ms appendString:@">"];
137   return ms;
138 }
139
140 /* logging */
141
142 - (NSString *)loggingPrefix {
143   return [NSString stringWithFormat:@"[so-objc-class:%@]", 
144                      NSStringFromClass(self->clazz)];
145 }
146 - (BOOL)isDebuggingEnabled {
147   static int debugOn = -1;
148   if (debugOn == -1) {
149     debugOn = [[NSUserDefaults standardUserDefaults]
150                 boolForKey:@"SoObjCClassDebugEnabled"] ? 1 : 0;
151   }
152   return debugOn ? YES : NO;
153 }
154
155 @end /* SoObjCClass */