]> err.no Git - sope/blob - sope-appserver/NGObjWeb/DynamicElements/WOComponentReference.m
fixed bundle resource lookup on MacOSX, changed resource lookup in
[sope] / sope-appserver / NGObjWeb / DynamicElements / WOComponentReference.m
1 /*
2   Copyright (C) 2000-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 "WOComponentReference.h"
23 #include "WOElement+private.h"
24 #include "WOContext+private.h"
25 #include "WOComponent+private.h"
26 #include "common.h"
27
28 @interface WOContext(ComponentStackCount)
29 - (unsigned)componentStackCount;
30 @end
31
32 @implementation WOComponentReference
33
34 static int   profileComponents = -1;
35 static BOOL  coreOnRecursion   = NO;
36 static BOOL  debugOn           = NO;
37 static Class NSDateClass = Nil;
38
39 + (void)initialize {
40   NSUserDefaults *ud = [NSUserDefaults standardUserDefaults];
41   
42   profileComponents = [[ud objectForKey:@"WOProfileComponents"]
43                            boolValue] ? 1 : 0;
44   coreOnRecursion = [ud boolForKey:@"WOCoreOnRecursiveSubcomponents"];
45   NSDateClass = [NSDate class];
46 }
47
48 - (id)initWithName:(NSString *)_name
49   associations:(NSDictionary *)_config
50   template:(WOElement *)_c
51 {
52   if ((self = [super initWithName:_name associations:_config template:_c])) {
53     self->containsForm    = YES;
54     self->activeComponent = OWGetProperty(_config, @"component");
55     self->bindings        = [_config copyWithZone:[self zone]];
56     [(NSMutableDictionary *)_config removeAllObjects];
57     
58     self->template = [_c retain];
59   }
60   return self;
61 }
62
63 - (void)dealloc {
64   [self->template        release];
65   [self->bindings        release];
66   [self->activeComponent release];
67   [self->child           release];
68   [super dealloc];
69 }
70
71 /* accessors */
72
73 - (WOComponent *)childComponent {
74   return self->child;
75 }
76
77 static inline void
78 _updateComponent(WOComponentReference *self, WOContext *_ctx)
79 {
80   if (self->activeComponent) {
81     WOComponent *newChild;
82
83     newChild = [self->activeComponent valueInComponent:[_ctx component]];
84
85 #if 0
86     if (newChild == nil) {
87       [[_ctx component] logWithFormat:
88                           @"missing child (got nil) "
89                           @"(element=%@, association=%@, component=%@).",
90                           self, self->activeComponent,
91                           [[_ctx component] name]];
92     }
93 #endif
94     
95     if (newChild != self->child) {
96       //NSLog(@"switched component %@ => %@ ...",
97       //      [self->child name], [newChild name]);
98       ASSIGN(self->child, newChild);
99       [newChild setParent:[_ctx component]];
100       [newChild setBindings:self->bindings];
101     }
102   }
103 }
104
105 // ******************** responder ********************
106
107 - (void)takeValuesFromRequest:(WORequest *)_req inContext:(WOContext *)_ctx {
108   WOComponent *parent;
109
110   parent = [_ctx component];
111   
112   _updateComponent(self, _ctx);
113
114   if (self->child) {
115     [_ctx enterComponent:self->child content:self->template];
116     [self->child takeValuesFromRequest:_req inContext:_ctx];
117     [_ctx leaveComponent:self->child];
118   }
119 }
120
121 - (id)invokeActionForRequest:(WORequest *)_req inContext:(WOContext *)_ctx {
122   WOComponent *parent;
123   id result    = nil;
124
125   parent = [_ctx component];
126
127   _updateComponent(self, _ctx);
128
129   if (self->child) {
130     [_ctx enterComponent:self->child content:self->template];
131     result = [self->child invokeActionForRequest:_req inContext:_ctx];
132     [_ctx leaveComponent:self->child];
133   }
134   
135   return result;
136 }
137
138 - (void)appendToResponse:(WOResponse *)_response inContext:(WOContext *)_ctx {
139   WOComponent *parent;
140   
141   parent = [_ctx component];
142   
143   _updateComponent(self, _ctx);
144   
145   if (self->child == parent) {
146     [self debugWithFormat:@"WARNING: recursive call of component: %@", parent];
147     if (coreOnRecursion)
148       abort();
149   }
150   
151   if (self->child) {
152     NSTimeInterval st = 0.0;
153
154     if (profileComponents)
155       st = [[NSDateClass date] timeIntervalSince1970];
156     
157     [_ctx enterComponent:self->child content:self->template];
158     [self->child appendToResponse:_response inContext:_ctx];
159     [_ctx leaveComponent:self->child];
160
161     if (profileComponents) {
162       NSTimeInterval diff;
163       int i;
164       diff = [[NSDateClass date] timeIntervalSince1970] - st;
165       for (i = [_ctx componentStackCount]; i >= 0; i--)
166         printf("  ");
167       printf("[%s %s]: %0.3fs\n",
168              [[child name] cString], 
169 #if APPLE_RUNTIME || NeXT_RUNTIME
170              sel_getName(_cmd), 
171 #else
172              sel_get_name(_cmd), 
173 #endif
174              diff);
175     }
176   }
177   else if (debugOn) {
178     [self debugWithFormat:@"missing component for reference: %@",
179             self->activeComponent];
180     [_response appendContentHTMLString:@"[missing component for reference: "];
181     [_response appendContentHTMLString:[self->activeComponent description]];
182     [_response appendContentHTMLString:@"]"];
183   }
184 }
185
186 /* description */
187
188 - (NSString *)description {
189   NSMutableString *desc = [NSMutableString stringWithCapacity:64];
190   
191   [desc appendFormat:@"<%@[0x%08X]:", NSStringFromClass([self class]), self];
192   
193   if (self->child) {
194     [desc appendFormat:@" child=%@[0x%08X] childName=%@",
195             NSStringFromClass([self->child class]),
196             self->child, [self->child name]];
197   }
198   
199   [desc appendString:@">"];
200   return desc;
201 }
202
203 @end /* WOComponentReference */