2 Copyright (C) 2002-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 <NGObjWeb/WOxElemBuilder.h>
26 This builder builds references to subcomponents. The subcomponent name is
27 derived from the tagname.
29 NOTE: this builder is a "final destination" for all bind(var) namespace
36 <var:script src=...>....</var:script> maps to a component script part ...
37 <var:component className=... /> maps to WOSwitchComponent
41 @interface WOxComponentElemBuilder : WOxElemBuilder
47 #include <SaxObjC/XMLNamespaces.h>
48 #include <DOM/DOMProtocols.h>
49 #include <DOM/DOMText.h>
50 #include <NGObjWeb/WOAssociation.h>
51 #include <NGObjWeb/WOComponentScript.h>
52 #include "WOChildComponentReference.h"
55 @interface NSObject(LineInfo)
59 @implementation WOxComponentElemBuilder
61 static BOOL debugOn = NO;
64 NSUserDefaults *ud = [NSUserDefaults standardUserDefaults];
66 [[ud objectForKey:@"WOxComponentElemBuilderDebugEnabled"] boolValue];
69 /* extracting associations */
71 - (NSMutableDictionary *)associationsForAttributes:(id<DOMNamedNodeMap>)_attrs
72 templateBuilder:(id)_b
74 NSMutableDictionary *assocs;
76 if ((assocs = [_b associationsForAttributes:_attrs]) == nil)
79 // should we check the tag or do we always remove className ?
80 if ([assocs objectForKey:@"className"])
81 [assocs removeObjectForKey:@"className"];
82 else if ([assocs objectForKey:@"value"])
83 [assocs removeObjectForKey:@"value"];
87 /* building elements */
89 - (WOElement *)buildComponentReferenceElement:(id<DOMElement>)_element
90 templateBuilder:(id)_b
93 TODO: I don't think that this already works - it uses the 'value'
94 binding but WOComponentReference expects 'component'
96 static Class LiveChildRefClass = Nil;
97 NSMutableDictionary *assocs;
102 if (LiveChildRefClass == Nil)
103 LiveChildRefClass = NSClassFromString(@"WOComponentReference");
106 [self debugWithFormat:@"build component-reference: %@",_element];
108 value = [_element attribute:@"value" namespaceURI:XMLNS_OD_BIND];
109 if ([value length] == 0) return nil;
111 /* construct child elements */
113 children = [_element hasChildNodes]
114 ? [_b buildNodes:[_element childNodes] templateBuilder:_b]
117 /* build associations */
119 assocs = [self associationsForAttributes:[_element attributes]
121 [assocs setObject:[WOAssociation associationWithKeyPath:value]
122 forKey:@"component"];
127 [self debugWithFormat:
128 @" create reference for keypath: '%@': children=%@, assocs=%@",
129 value, children, assocs];
132 de = [[LiveChildRefClass alloc]
133 initWithName:[_b uniqueIDForNode:_element]
135 contentElements:children];
136 if (debugOn) [self debugWithFormat:@" built: %@", de];
140 - (WOElement *)processScriptElement:(id<DOMElement>)_e templateBuilder:(id)_b {
141 /* process a component related script */
144 [self debugWithFormat:@"processing script element: %@", _e];
146 /* first process src attribute ... */
147 if ((src = [_e attribute:@"src" namespaceURI:XMLNS_OD_BIND])) {
148 /* create script part for src ... */
149 [self logWithFormat:@"create script part for src '%@', not implemented",
153 /* create script part for content ... */
154 if ([_e hasChildNodes]) {
155 WOComponentScriptPart *lscript;
158 NSMutableString *content;
162 content = [[NSMutableString alloc] initWithCapacity:256];
164 line = ([(NSObject *)_e respondsToSelector:@selector(line)])
169 e = [(NSArray *)[_e childNodes] objectEnumerator];
170 while ((subnode = [e nextObject])) {
171 [content appendString:[subnode textValue]];
174 lscript = [WOComponentScriptPart alloc];
175 lscript = [lscript initWithURL:url startLine:line script:content];
178 [_b addComponentScriptPart:lscript];
185 - (WOElement *)buildElement:(id<DOMElement>)_element templateBuilder:(id)_b {
186 static Class ChildRefClass = Nil;
187 NSMutableDictionary *bindings;
193 if (![[_element namespaceURI] isEqualToString:XMLNS_OD_BIND]) {
195 [self debugWithFormat:
196 @"do not process element, not in bind namespace: %@", _element];
201 tagName = [_element tagName];
204 if ([tagName isEqualToString:@"script"])
205 return [self processScriptElement:_element templateBuilder:_b];
207 if ([tagName isEqualToString:@"component"]) {
208 compName = [_element attribute:@"className" namespaceURI:XMLNS_OD_BIND];
209 if ([compName length] == 0) {
210 compName = [_element attribute:@"classname"
211 namespaceURI:XMLNS_OD_BIND];
213 if ([compName length] == 0)
214 compName = [_element attribute:@"name" namespaceURI:XMLNS_OD_BIND];
216 /* check whether we should use a "live" reference to a component object */
218 if ([compName length] == 0) {
221 value = [_element attribute:@"value" namespaceURI:XMLNS_OD_BIND];
222 if ([value length] > 0) {
223 return [self buildComponentReferenceElement:_element
228 if ([compName length] == 0) {
230 @"missing 'name' or 'value' attribute in var:component: %@",
231 [_element attributes]];
236 [self logWithFormat:@"Creating component %@ using tag. "
237 @"<var:component name='%@'/> is preferred !",
242 [self debugWithFormat:@"creating static component reference: %@",_element];
244 if (ChildRefClass == Nil)
245 ChildRefClass = NSClassFromString(@"WOChildComponentReference");
247 cid = [_b uniqueIDForNode:_element];
249 [self debugWithFormat:@"BUILD Component(%@): %@", cid, _element];
251 /* construct child elements */
253 children = [_element hasChildNodes]
254 ? [_b buildNodes:[_element childNodes] templateBuilder:_b]
258 compName = [_element tagName];
260 bindings = [self associationsForAttributes:[_element attributes]
263 [self debugWithFormat:@" using bindings: %@", bindings];
265 [_b registerSubComponentWithId:cid
266 componentName:compName
269 return [[ChildRefClass alloc]
272 contentElements:children];
277 - (BOOL)isDebuggingEnabled {
281 @end /* WOxComponentElemBuilder */