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 "WOGenericElement.h"
23
#include "WOElement+private.h"
25
#include <NGObjWeb/WOxElemBuilder.h>
26
#include <DOM/DOMProtocols.h>
28
// TODO: we should be able to store the key as ASCII ?
29
// TODO: does it make sense to resolve constant associations ?
30
// all constant assocs could be joined at init time ?
32
#define TagNameType_Assoc 0
33
#define TagNameType_String 1
34
#define TagNameType_ASCII 2
41
@implementation WOGenericElement
43
- (id)initWithElement:(id<DOMElement>)_element
44
templateBuilder:(WOxElemBuilder *)_builder
47
NSMutableDictionary *assocs;
49
id<NSObject,DOMNamedNodeMap> attrs;
52
name = [_element tagName];
54
/* construct associations */
57
attrs = [_element attributes];
58
if ((lcount = [attrs length]) > 0)
59
assocs = [_builder associationsForAttributes:attrs];
63
[NSMutableDictionary dictionaryWithObject:
64
[_builder associationForValue:[_element tagName]]
65
forKey:@"elementName"];
68
[assocs setObject:[_builder associationForValue:[_element tagName]]
69
forKey:@"elementName"];
72
/* construct child elements */
74
children = [_element hasChildNodes]
75
? [_builder buildNodes:[_element childNodes] templateBuilder:_builder]
78
/* construct self ... */
79
self = [(WODynamicElement *)self initWithName:name
81
contentElements:children];
85
- (BOOL)_isASCIIString:(NSString *)_s {
86
/* TODO: not a very fast check for an ASCII string ... */
87
return [_s dataUsingEncoding:NSASCIIStringEncoding
88
allowLossyConversion:NO] != nil ? YES : NO;
91
- (void)_setupAssociations:(NSMutableDictionary *)_associations {
94
OWAttribute *mapping = NULL;
99
keys = [_associations keyEnumerator];
100
self->mappings = calloc(self->count, sizeof(OWAttribute));
102
for (mapping = self->mappings; (key = [keys nextObject]); mapping++) {
103
WOAssociation *value;
105
value = [_associations objectForKey:key];
106
mapping->key = [key copy];
107
mapping->value = [value retain];
109
[_associations removeAllObjects];
112
- (void)_configureForConstantElementName:(NSString *)s {
113
if ([self _isASCIIString:s]) {
117
len = [s cStringLength];
118
cs = malloc(len + 2);
122
self->tagNameType = TagNameType_ASCII;
125
/* a tagname which is not ASCII ?? */
126
self->tagName = [s copy];
127
self->tagNameType = TagNameType_String;
131
- (id)initWithName:(NSString *)_name
132
associations:(NSDictionary *)_associations
133
template:(WOElement *)_template
135
self = [super initWithName:_name
136
associations:_associations
142
self->tagName = a = OWGetProperty(_associations, @"elementName");
143
self->tagNameType = TagNameType_Assoc;
144
self->count = [_associations count];
146
if ([a isValueConstant]) {
147
[self _configureForConstantElementName:[a stringValueInComponent:nil]];
148
[a release]; a = nil;
152
[self _setupAssociations:(NSMutableDictionary *)_associations];
158
if (self->mappings) {
162
for (cnt = 0, map = self->mappings; cnt < self->count; cnt++, map++) {
163
[map->key release]; map->key = nil;
164
[map->value release]; map->value = nil;
166
if (self->mappings) free(self->mappings);
167
self->mappings = NULL;
170
switch (self->tagNameType) {
171
case TagNameType_Assoc: [(id)self->tagName release]; break;
172
case TagNameType_String: [(id)self->tagName release]; break;
173
case TagNameType_ASCII:
174
if (self->tagName) free(self->tagName);
177
NSLog(@"ERROR: unknown tag-name-type %i !", self->tagNameType);
183
/* response generation */
185
- (void)_appendAttributesToResponse:(WOResponse *)_response
186
inContext:(WOContext *)_ctx
188
// TODO: this seems to take some time during profiling, maybe we can
189
// optimize that (ASCII keys, constant assocs)
190
WOComponent *sComponent = [_ctx component];
194
for (cnt = 0, map = self->mappings; cnt < self->count; cnt++, map++) {
197
if ((value = [map->value valueInComponent:sComponent]) == nil)
200
WOResponse_AddChar(_response, ' ');
201
WOResponse_AddString(_response, map->key);
202
WOResponse_AddCString(_response, "=\"");
203
WOResponse_AddHtmlString(_response, [value stringValue]);
204
WOResponse_AddChar(_response, '"');
208
- (void)appendToResponse:(WOResponse *)_response inContext:(WOContext *)_ctx {
209
WOComponent *sComponent;
212
if ([[_ctx request] isFromClientComponent])
215
sComponent = [_ctx component];
217
WOResponse_AddChar(_response, '<');
218
switch (self->tagNameType) {
219
case TagNameType_Assoc:
220
tag = [(id)self->tagName stringValueInComponent:sComponent];
221
WOResponse_AddString(_response, tag);
223
case TagNameType_String:
224
WOResponse_AddString(_response, self->tagName);
226
case TagNameType_ASCII:
227
WOResponse_AddCString(_response, self->tagName);
231
[self _appendAttributesToResponse:_response inContext:_ctx];
233
if (self->otherTagString) {
234
WOResponse_AddChar(_response, ' ');
235
WOResponse_AddString(_response,
236
[self->otherTagString stringValueInComponent:
239
WOResponse_AddCString(_response, " />");
242
@end /* WOGenericElement */