2 Copyright (C) 2000-2005 SKYRIX Software AG
4 This file is part of SOPE.
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
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.
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
22 #include "WOCompoundElement.h"
23 #include "WOElement+private.h"
24 #include <NGObjWeb/WOContext.h>
27 #if APPLE_RUNTIME || NeXT_RUNTIME
28 # include <objc/objc-class.h>
31 @interface WOContext(ComponentStackCount)
32 - (unsigned)componentStackCount;
35 @implementation WOCompoundElement
38 static int profElements = -1;
39 static int embedInPool = -1;
40 static int logId = -1;
41 static Class NSDateClass = Nil;
43 static int descriptiveIDs = -1;
46 NSUserDefaults *ud = [NSUserDefaults standardUserDefaults];
48 if (descriptiveIDs == -1) {
50 [[ud objectForKey:@"WODescriptiveElementIDs"] boolValue] ? 1 : 0;
54 if (profElements == -1) {
55 profElements = [[[NSUserDefaults standardUserDefaults]
56 objectForKey:@"WOProfileElements"]
59 if (embedInPool == -1) {
60 embedInPool = [[[NSUserDefaults standardUserDefaults]
61 objectForKey:@"WOCompoundElementPool"]
63 NSLog(@"WOCompoundElement: pool embedding is on.");
66 logId = [[[NSUserDefaults standardUserDefaults]
67 objectForKey:@"WOCompoundElementLogID"]
69 NSLog(@"WOCompoundElement: id logging is on.");
74 + (id)allocForCount:(int)_count zone:(NSZone *)_zone {
75 return NSAllocateObject(self, _count * sizeof(WOElement *), _zone);
78 - (id)initWithContentElements:(NSArray *)_children {
79 WOElement *(*objAtIdx)(id, SEL, int);
82 if (_children == nil) {
83 NSLog(@"%@: invalid argument ..", self);
84 self = [self autorelease];
90 objAtIdx = (void *)[_children methodForSelector:
91 @selector(objectAtIndex:)];
92 NSAssert1(objAtIdx != NULL,
93 @"could not get -objectAtIndex: method of %@",
96 self->count = [_children count];
97 for (i = (self->count - 1); i >= 0; i--) {
98 register WOElement *child;
100 child = objAtIdx(_children, @selector(objectAtIndex:), i);
102 self->children[i] = [child retain];
107 - (id)initWithChildren:(NSArray *)_children {
108 return [self initWithContentElements:_children];
111 return [self initWithContentElements:nil];
116 for (i = 0; i < self->count; i++) {
117 [self->children[i] release];
118 self->children[i] = nil;
125 - (NSArray *)subelements {
126 if (self->count == 0)
129 return [NSArray arrayWithObjects:self->children count:self->count];
134 - (void)takeValuesFromRequest:(WORequest *)_rq inContext:(WOContext *)_ctx {
135 void (*incId)(id, SEL);
139 [_ctx methodForSelector:@selector(incrementLastElementIDComponent)];
142 [_ctx appendElementIDComponent:@"c0"];
144 [_ctx appendZeroElementIDComponent];
146 for (i = 0; i < self->count; i++) {
147 register WOElement *child = self->children[i];
149 if (child->takeValues) {
150 child->takeValues(child,
151 @selector(takeValuesFromRequest:inContext:),
155 [child takeValuesFromRequest:_rq inContext:_ctx];
157 if (descriptiveIDs) {
158 [_ctx deleteLastElementIDComponent];
159 [_ctx appendElementIDComponent:
160 [NSString stringWithFormat:@"c%i", i]];
163 incId(_ctx, @selector(incrementLastElementIDComponent));
165 [_ctx deleteLastElementIDComponent];
168 - (id)invokeActionForRequest:(WORequest *)_rq inContext:(WOContext *)_ctx {
172 if ((idxId = [_ctx currentElementID])) {
173 int idx = [idxId intValue];
175 idx = (descriptiveIDs)
176 ? [[idxId substringFromIndex:1] intValue]
179 [_ctx consumeElementID]; // consume index-id
181 if ((idx < 0) || (idx >= self->count)) {
182 [[_ctx session] logWithFormat:
183 @"%s: invalid element id, %i is out of range (0-%i) !",
185 idx, (self->count - 1)];
189 [_ctx appendElementIDComponent:idxId];
190 result = [self->children[idx] invokeActionForRequest:_rq inContext:_ctx];
191 [_ctx deleteLastElementIDComponent];
195 logWithFormat:@"%s: MISSING INDEX ID in URL: %@ !",
202 - (void)appendToResponse:(WOResponse *)_response inContext:(WOContext *)_ctx {
203 static int depth = 0;
204 void (*incId)(id, SEL);
207 #if USE_EXCEPTION_HANDLER
208 static NSString *cName = @"componentName";
209 static NSString *elemId = @"elementID";
211 NSTimeInterval st = 0.0;
213 if (NSDateClass == Nil)
214 NSDateClass = [NSDate class];
219 #if defined(DEBUG) && USE_EXCEPTION_HANDLER
225 st = [[NSDateClass date] timeIntervalSince1970];
229 [_ctx methodForSelector:@selector(incrementLastElementIDComponent)];
232 [_ctx appendElementIDComponent:@"c0"];
234 [_ctx appendZeroElementIDComponent];
236 for (i = 0; i < self->count; i++) {
237 register WOElement *child = self->children[i];
239 NSAutoreleasePool *pool = nil;
240 NSTimeInterval st = 0.0;
241 if (embedInPool) pool = [[NSAutoreleasePool alloc] init];
243 st = [[NSDateClass date] timeIntervalSince1970];
246 if (child->appendResponse) {
247 child->appendResponse(child,
248 @selector(appendToResponse:inContext:),
252 [child appendToResponse:_response inContext:_ctx];
258 diff = [[NSDateClass date] timeIntervalSince1970] - st;
261 for (j = [_ctx componentStackCount] + depth; j >= 0; j--)
264 printf(" Child of 0x%p: i[%i] %s <%s>: %0.3fs\n",
265 self, i, [[_ctx elementID] cString], [child class]->name,
270 NSLog(@"WOCompoundElement: pool will release ... (lastId=%@)",
276 if (descriptiveIDs) {
277 [_ctx deleteLastElementIDComponent];
278 [_ctx appendElementIDComponent:
279 [NSString stringWithFormat:@"c%i", i]];
282 incId(_ctx, @selector(incrementLastElementIDComponent));
284 [_ctx deleteLastElementIDComponent];
290 diff = [[NSDateClass date] timeIntervalSince1970] - st;
292 for (i = [_ctx componentStackCount] + depth; i >= 0; i--)
295 printf("CompoundElem0x%p(#%i) %s (component=%s): %0.3fs\n",
296 self, self->count, [[_ctx elementID] cString],
297 [[(WOComponent *)[_ctx component] name] cString],
302 #if defined(DEBUG) && USE_EXCEPTION_HANDLER
305 NSMutableDictionary *ui;
308 ui = [[localException userInfo] mutableCopy];
309 if (ui == nil) ui = [[NSMutableDictionary alloc] init];
311 if ((tmp = [ui objectForKey:cName]) == nil)
312 [ui setObject:[[_ctx component] name] forKey:cName];
313 if ((tmp = [ui objectForKey:elemId]) == nil)
314 [ui setObject:[_ctx elementID] forKey:elemId];
316 [localException setUserInfo:ui];
317 [ui release]; ui = nil;
319 [localException raise];
329 - (NSString *)associationDescription {
330 NSMutableString *str = [NSMutableString stringWithCapacity:256];
333 [str appendString:@"children=\n"];
334 for (i = 0; i < self->count; i++) {
335 [str appendString:@" "];
336 [str appendString:[self->children[i] description]];
337 [str appendString:@"\n"];
342 @end /* WOCompoundElement */
344 @implementation WOHTMLStaticGroup
346 /* this element was discovered in SSLContainer.h and may not be public */
348 @end /* WOHTMLStaticGroup */