~ubuntu-branches/ubuntu/edgy/sope/edgy

« back to all changes in this revision

Viewing changes to sope-appserver/NGObjWeb/DynamicElements/WOGenericElement.m

  • Committer: Bazaar Package Importer
  • Author(s): Sebastian Ley
  • Date: 2005-08-19 16:53:31 UTC
  • Revision ID: james.westby@ubuntu.com-20050819165331-hs683wz1osm708pw
Tags: upstream-4.4rc.2
ImportĀ upstreamĀ versionĀ 4.4rc.2

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
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 "WOGenericElement.h"
 
23
#include "WOElement+private.h"
 
24
#include "common.h"
 
25
#include <NGObjWeb/WOxElemBuilder.h>
 
26
#include <DOM/DOMProtocols.h>
 
27
 
 
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 ?
 
31
 
 
32
#define TagNameType_Assoc  0
 
33
#define TagNameType_String 1
 
34
#define TagNameType_ASCII  2
 
35
 
 
36
typedef struct {
 
37
  NSString      *key;
 
38
  WOAssociation *value;
 
39
} OWAttribute;
 
40
 
 
41
@implementation WOGenericElement
 
42
 
 
43
- (id)initWithElement:(id<DOMElement>)_element
 
44
  templateBuilder:(WOxElemBuilder *)_builder
 
45
{
 
46
  NSString            *name;
 
47
  NSMutableDictionary *assocs;
 
48
  NSArray             *children;
 
49
  id<NSObject,DOMNamedNodeMap> attrs;
 
50
  unsigned lcount;
 
51
  
 
52
  name  = [_element tagName];
 
53
  
 
54
  /* construct associations */
 
55
 
 
56
  assocs = nil;
 
57
  attrs = [_element attributes];
 
58
  if ((lcount = [attrs length]) > 0)
 
59
    assocs = [_builder associationsForAttributes:attrs];
 
60
 
 
61
  if (assocs == nil) {
 
62
    assocs = 
 
63
      [NSMutableDictionary dictionaryWithObject:
 
64
                             [_builder associationForValue:[_element tagName]]
 
65
                           forKey:@"elementName"];
 
66
  }
 
67
  else {
 
68
    [assocs setObject:[_builder associationForValue:[_element tagName]]
 
69
            forKey:@"elementName"];
 
70
  }
 
71
  
 
72
  /* construct child elements */
 
73
 
 
74
  children = [_element hasChildNodes]
 
75
    ? [_builder buildNodes:[_element childNodes] templateBuilder:_builder]
 
76
    : nil;
 
77
  
 
78
  /* construct self ... */
 
79
  self = [(WODynamicElement *)self initWithName:name 
 
80
                                   associations:assocs 
 
81
                                   contentElements:children];
 
82
  return self;
 
83
}
 
84
 
 
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;
 
89
}
 
90
 
 
91
- (void)_setupAssociations:(NSMutableDictionary *)_associations {
 
92
  NSEnumerator *keys;
 
93
  NSString     *key     = nil;
 
94
  OWAttribute  *mapping = NULL;
 
95
  
 
96
  if (self->count == 0)
 
97
    return;
 
98
  
 
99
  keys           = [_associations keyEnumerator];
 
100
  self->mappings = calloc(self->count, sizeof(OWAttribute));
 
101
  
 
102
  for (mapping = self->mappings; (key = [keys nextObject]); mapping++) {
 
103
    WOAssociation *value;
 
104
        
 
105
    value = [_associations objectForKey:key];
 
106
    mapping->key   = [key copy];
 
107
    mapping->value = [value retain];
 
108
  }
 
109
  [_associations removeAllObjects];
 
110
}
 
111
 
 
112
- (void)_configureForConstantElementName:(NSString *)s {
 
113
  if ([self _isASCIIString:s]) {
 
114
    unsigned char *cs;
 
115
    unsigned len;
 
116
        
 
117
    len = [s cStringLength];
 
118
    cs = malloc(len + 2);
 
119
    [s getCString:cs];
 
120
    cs[len] = '\0';
 
121
    self->tagName = cs;
 
122
    self->tagNameType = TagNameType_ASCII;
 
123
  }
 
124
  else {
 
125
    /* a tagname which is not ASCII ?? */
 
126
    self->tagName = [s copy];
 
127
    self->tagNameType = TagNameType_String;
 
128
  }
 
129
}
 
130
 
 
131
- (id)initWithName:(NSString *)_name
 
132
  associations:(NSDictionary *)_associations
 
133
  template:(WOElement *)_template
 
134
{
 
135
  self = [super initWithName:_name
 
136
                associations:_associations
 
137
                template:_template];
 
138
  
 
139
  if (self) {
 
140
    WOAssociation *a;
 
141
    
 
142
    self->tagName     = a = OWGetProperty(_associations, @"elementName");
 
143
    self->tagNameType = TagNameType_Assoc;
 
144
    self->count   = [_associations count];
 
145
    
 
146
    if ([a isValueConstant]) {
 
147
      [self _configureForConstantElementName:[a stringValueInComponent:nil]];
 
148
      [a release]; a = nil;
 
149
    }
 
150
    
 
151
    if (self->count > 0)
 
152
      [self _setupAssociations:(NSMutableDictionary *)_associations];
 
153
  }
 
154
  return self;
 
155
}
 
156
 
 
157
- (void)dealloc {
 
158
  if (self->mappings) {
 
159
    OWAttribute *map;
 
160
    unsigned cnt;
 
161
 
 
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;
 
165
    }
 
166
    if (self->mappings) free(self->mappings);
 
167
    self->mappings = NULL;
 
168
  }
 
169
  
 
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);
 
175
      break;
 
176
    default:
 
177
      NSLog(@"ERROR: unknown tag-name-type %i !", self->tagNameType);
 
178
      break;
 
179
  }
 
180
  [super dealloc];
 
181
}
 
182
 
 
183
/* response generation */
 
184
 
 
185
- (void)_appendAttributesToResponse:(WOResponse *)_response
 
186
  inContext:(WOContext *)_ctx
 
187
{
 
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];
 
191
  OWAttribute *map;
 
192
  unsigned cnt;
 
193
  
 
194
  for (cnt = 0, map = self->mappings; cnt < self->count; cnt++, map++) {
 
195
    register id value;
 
196
    
 
197
    if ((value = [map->value valueInComponent:sComponent]) == nil)
 
198
      continue;
 
199
 
 
200
    WOResponse_AddChar(_response, ' ');
 
201
    WOResponse_AddString(_response, map->key);
 
202
    WOResponse_AddCString(_response, "=\"");
 
203
    WOResponse_AddHtmlString(_response, [value stringValue]);
 
204
    WOResponse_AddChar(_response, '"');
 
205
  }
 
206
}
 
207
 
 
208
- (void)appendToResponse:(WOResponse *)_response inContext:(WOContext *)_ctx {
 
209
  WOComponent *sComponent;
 
210
  NSString    *tag;
 
211
  
 
212
  if ([[_ctx request] isFromClientComponent])
 
213
    return;
 
214
  
 
215
  sComponent = [_ctx component];
 
216
  
 
217
  WOResponse_AddChar(_response, '<');
 
218
  switch (self->tagNameType) {
 
219
    case TagNameType_Assoc:
 
220
      tag = [(id)self->tagName stringValueInComponent:sComponent];
 
221
      WOResponse_AddString(_response, tag);
 
222
      break;
 
223
    case TagNameType_String:
 
224
      WOResponse_AddString(_response, self->tagName);
 
225
      break;
 
226
    case TagNameType_ASCII:
 
227
      WOResponse_AddCString(_response, self->tagName);
 
228
      break;
 
229
  }
 
230
  
 
231
  [self _appendAttributesToResponse:_response inContext:_ctx];
 
232
  
 
233
  if (self->otherTagString) {
 
234
    WOResponse_AddChar(_response, ' ');
 
235
    WOResponse_AddString(_response,
 
236
                         [self->otherTagString stringValueInComponent:
 
237
                           sComponent]);
 
238
  }
 
239
  WOResponse_AddCString(_response, " />");
 
240
}
 
241
 
 
242
@end /* WOGenericElement */