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 Class NSDateClass = Nil;
41 static int descriptiveIDs = -1;
43 + (id)allocForCount:(int)_count zone:(NSZone *)_zone {
44 return NSAllocateObject(self, _count * sizeof(WOElement *), _zone);
47 - (id)initWithContentElements:(NSArray *)_children {
48 WOElement *(*objAtIdx)(id, SEL, int);
51 if (_children == nil) {
52 NSLog(@"%@: invalid argument ..", self);
53 self = [self autorelease];
59 if (descriptiveIDs == -1) {
61 [[[NSUserDefaults standardUserDefaults]
62 objectForKey:@"WODescriptiveElementIDs"]
66 objAtIdx = (void *)[_children methodForSelector:
67 @selector(objectAtIndex:)];
68 NSAssert1(objAtIdx != NULL,
69 @"could not get -objectAtIndex: method of %@",
72 self->count = [_children count];
73 for (i = (self->count - 1); i >= 0; i--) {
74 register WOElement *child;
76 child = objAtIdx(_children, @selector(objectAtIndex:), i);
78 self->children[i] = [child retain];
83 - (id)initWithChildren:(NSArray *)_children {
84 return [self initWithContentElements:_children];
87 return [self initWithContentElements:nil];
92 for (i = 0; i < self->count; i++) {
93 [self->children[i] release];
94 self->children[i] = nil;
101 - (NSArray *)subelements {
102 if (self->count == 0)
105 return [NSArray arrayWithObjects:self->children count:self->count];
110 - (void)takeValuesFromRequest:(WORequest *)_rq inContext:(WOContext *)_ctx {
111 void (*incId)(id, SEL);
115 [_ctx methodForSelector:@selector(incrementLastElementIDComponent)];
118 [_ctx appendElementIDComponent:@"c0"];
120 [_ctx appendZeroElementIDComponent];
122 for (i = 0; i < self->count; i++) {
123 register WOElement *child = self->children[i];
125 if (child->takeValues) {
126 child->takeValues(child,
127 @selector(takeValuesFromRequest:inContext:),
131 [child takeValuesFromRequest:_rq inContext:_ctx];
133 if (descriptiveIDs) {
134 [_ctx deleteLastElementIDComponent];
135 [_ctx appendElementIDComponent:
136 [NSString stringWithFormat:@"c%i", i]];
139 incId(_ctx, @selector(incrementLastElementIDComponent));
141 [_ctx deleteLastElementIDComponent];
144 - (id)invokeActionForRequest:(WORequest *)_rq inContext:(WOContext *)_ctx {
148 if ((idxId = [_ctx currentElementID])) {
149 int idx = [idxId intValue];
151 idx = (descriptiveIDs)
152 ? [[idxId substringFromIndex:1] intValue]
155 [_ctx consumeElementID]; // consume index-id
157 if ((idx < 0) || (idx >= self->count)) {
158 [[_ctx session] logWithFormat:
159 @"%s: invalid element id, %i is out of range (0-%i) !",
161 idx, (self->count - 1)];
165 [_ctx appendElementIDComponent:idxId];
166 result = [self->children[idx] invokeActionForRequest:_rq inContext:_ctx];
167 [_ctx deleteLastElementIDComponent];
171 logWithFormat:@"%s: MISSING INDEX ID in URL: %@ !",
178 - (void)appendToResponse:(WOResponse *)_response inContext:(WOContext *)_ctx {
179 static int depth = 0;
180 void (*incId)(id, SEL);
183 #if USE_EXCEPTION_HANDLER
184 static NSString *cName = @"componentName";
185 static NSString *elemId = @"elementID";
187 static int embedInPool = -1;
188 static int logId = -1;
189 NSTimeInterval st = 0.0;
191 if (NSDateClass == Nil)
192 NSDateClass = [NSDate class];
194 if (profElements == -1) {
195 profElements = [[[NSUserDefaults standardUserDefaults]
196 objectForKey:@"WOProfileElements"]
199 if (embedInPool == -1) {
200 embedInPool = [[[NSUserDefaults standardUserDefaults]
201 objectForKey:@"WOCompoundElementPool"]
203 NSLog(@"WOCompoundElement: pool embedding is on.");
206 logId = [[[NSUserDefaults standardUserDefaults]
207 objectForKey:@"WOCompoundElementLogID"]
209 NSLog(@"WOCompoundElement: id logging is on.");
215 #if defined(DEBUG) && USE_EXCEPTION_HANDLER
221 st = [[NSDateClass date] timeIntervalSince1970];
225 [_ctx methodForSelector:@selector(incrementLastElementIDComponent)];
228 [_ctx appendElementIDComponent:@"c0"];
230 [_ctx appendZeroElementIDComponent];
232 for (i = 0; i < self->count; i++) {
233 register WOElement *child = self->children[i];
235 NSAutoreleasePool *pool = nil;
236 NSTimeInterval st = 0.0;
237 if (embedInPool) pool = [[NSAutoreleasePool alloc] init];
239 st = [[NSDateClass date] timeIntervalSince1970];
242 if (child->appendResponse) {
243 child->appendResponse(child,
244 @selector(appendToResponse:inContext:),
248 [child appendToResponse:_response inContext:_ctx];
254 diff = [[NSDateClass date] timeIntervalSince1970] - st;
257 for (j = [_ctx componentStackCount] + depth; j >= 0; j--)
260 printf(" Child of 0x%08X: i[%i] %s <%s>: %0.3fs\n",
262 i, [[_ctx elementID] cString],
268 NSLog(@"WOCompoundElement: pool will release ... (lastId=%@)",
274 if (descriptiveIDs) {
275 [_ctx deleteLastElementIDComponent];
276 [_ctx appendElementIDComponent:
277 [NSString stringWithFormat:@"c%i", i]];
280 incId(_ctx, @selector(incrementLastElementIDComponent));
282 [_ctx deleteLastElementIDComponent];
288 diff = [[NSDateClass date] timeIntervalSince1970] - st;
290 for (i = [_ctx componentStackCount] + depth; i >= 0; i--)
293 printf("CompoundElem0x%08X(#%i) %s (component=%s): %0.3fs\n",
296 [[_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 */