]> err.no Git - sope/blob - Recycler/NGObjDOM/ODNodeRendererFactorySet.m
work on recurrences
[sope] / Recycler / NGObjDOM / ODNodeRendererFactorySet.m
1 /*
2   Copyright (C) 2000-2003 SKYRIX Software AG
3
4   This file is part of OGo
5
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
9   later version.
10
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.
15
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
19   02111-1307, USA.
20 */
21 // $Id$
22
23 #include <NGObjDOM/ODNodeRendererFactorySet.h>
24
25 @interface _ODNodeRendererFactorySetEntry : NSObject
26 {
27 @public
28   ODNodeRendererFactory *factory;
29   EOQualifier *qualifier;
30   NSString    *namespaceURI;
31   NSString    *tagName;
32 }
33
34 - (BOOL)matchesNode:(id)_node;
35 - (ODNodeRendererFactory *)nodeRendererFactory;
36
37 @end
38
39 #include <NGObjDOM/ODRNodeText.h>
40 #include <NGObjDOM/ODRGenericTag.h>
41 #include "common.h"
42 #include <EOControl/EOQualifier.h>
43
44 @implementation ODNodeRendererFactorySet
45
46 + (int)version {
47   return 1;
48 }
49
50 - (void)dealloc {
51   RELEASE(self->subfactories);
52   RELEASE(self->cache);
53   [super dealloc];
54 }
55
56 - (void)flushCache {
57   [self->cache removeAllObjects];
58 }
59
60 /* registry */
61
62 - (void)registerFactory:(id<NSObject,ODNodeRendererFactory>)_factory
63   forNodeQualifier:(EOQualifier *)_qualifier
64 {
65   _ODNodeRendererFactorySetEntry *entry;
66
67 #if DEBUG
68   if (![_factory conformsToProtocol:@protocol(ODNodeRendererFactory)]) {
69     NSLog(@"WARNING(%s): node-factory %@ to be registered, doesn't implement "
70           @"the ODNodeRendererFactory protocol !",
71           __PRETTY_FUNCTION__, _factory);
72   }
73 #endif
74   
75   [self flushCache];
76   
77   entry = [[_ODNodeRendererFactorySetEntry alloc] init];
78   entry->factory   = RETAIN(_factory);
79   entry->qualifier = RETAIN(_qualifier);
80
81   if (self->subfactories == nil)
82     self->subfactories = [[NSMutableArray alloc] initWithCapacity:4];
83   [self->subfactories addObject:entry];
84   RELEASE(entry);
85 }
86
87 - (void)registerFactory:(id<NSObject,ODNodeRendererFactory>)_factory
88   forNamespaceURI:(NSString *)_namespaceURI
89   tagName:(NSString *)_tagName
90 {
91   _ODNodeRendererFactorySetEntry *entry;
92   
93 #if DEBUG
94   if (![_factory conformsToProtocol:@protocol(ODNodeRendererFactory)]) {
95     NSLog(@"WARNING(%s): node-factory %@ to be registered, doesn't implement "
96           @"the ODNodeRendererFactory protocol !",
97           __PRETTY_FUNCTION__, _factory);
98   }
99 #endif
100
101   [self flushCache];
102   
103   entry = [[_ODNodeRendererFactorySetEntry alloc] init];
104   entry->factory      = RETAIN(_factory);
105   entry->namespaceURI = [_namespaceURI copy];
106   entry->tagName      = [_tagName copy];
107   
108   if (self->subfactories == nil)
109     self->subfactories = [[NSMutableArray alloc] initWithCapacity:4];
110   [self->subfactories addObject:entry];
111   RELEASE(entry);
112 }
113
114 - (void)registerFactory:(id<NSObject,ODNodeRendererFactory>)_factory
115   forNamespaceURI:(NSString *)_namespaceURI
116 {
117   [self registerFactory:_factory
118         forNamespaceURI:_namespaceURI
119         tagName:nil];
120 }
121
122
123 /* lookup */
124
125 - (ODNodeRenderer *)rendererForTextNode:(id)_domNode 
126   inContext:(WOContext *)_ctx
127 {
128   static id r = nil;
129   if (r == nil) r = [[ODRNodeText alloc] init];
130   return r;
131 }
132
133 - (ODNodeRenderer *)rendererForElementNode:(id)_domNode
134   inContext:(WOContext *)_ctx
135 {
136   ODNodeRenderer *renderer;
137   NSString *key;
138   unsigned i, count;
139
140   key = [NSString stringWithFormat:@"{%@}%@",
141                     [_domNode namespaceURI], [_domNode tagName]];
142
143   if ((renderer = [self->cache objectForKey:key]))
144     return renderer;
145
146 #if DEBUG && 0
147   NSLog(@"1st lookup renderer: %@", key);
148 #endif
149   
150   for (i = 0, count = [self->subfactories count]; i < count; i++) {
151     _ODNodeRendererFactorySetEntry *entry;
152     
153     entry = [self->subfactories objectAtIndex:i];
154
155     if ([entry matchesNode:_domNode]) {
156       renderer = [[entry nodeRendererFactory]
157                          rendererForNode:_domNode
158                          inContext:_ctx];
159       if (renderer) break;
160     }
161   }
162   
163   if (renderer == nil) {
164     /* default tag */
165     static id r = nil;
166     if (r == nil) r = [[ODRGenericTag alloc] init];
167     renderer = r;
168   }
169   
170   if (renderer) {
171     if (self->cache == nil)
172       self->cache = [[NSMutableDictionary alloc] initWithCapacity:64];
173     [self->cache setObject:renderer forKey:key];
174   }
175   
176   return renderer;
177 }
178
179 - (ODNodeRenderer *)rendererForNode:(id)_domNode
180   inContext:(WOContext *)_ctx
181 {
182   ODNodeRenderer *renderer;
183   
184   switch ([_domNode nodeType]) {
185     case DOM_TEXT_NODE:
186     case DOM_CDATA_SECTION_NODE:
187       renderer = [self rendererForTextNode:_domNode inContext:_ctx];
188       break;
189       
190     case DOM_ELEMENT_NODE:
191       renderer = [self rendererForElementNode:_domNode inContext:_ctx];
192       break;
193       
194     default: {
195       static id compoundRenderer = nil;
196
197       if (compoundRenderer == nil)
198         compoundRenderer = [[ODNodeRenderer alloc] init];
199       
200       renderer = compoundRenderer;
201       break;
202     }
203   }
204   return renderer;
205 }
206
207 /* description */
208
209 - (NSString *)description {
210   NSMutableString *ms;
211   
212   ms = [NSMutableString stringWithCapacity:32];
213   
214   [ms appendFormat:@"<0x%08X[%@]:", self, NSStringFromClass([self class])];
215   [ms appendFormat:@" factories=#%d", [self->subfactories count]];
216   [ms appendFormat:@">"];
217   
218   return ms;
219 }
220
221 @end /* ODNodeRendererFactorySet */
222
223 @implementation _ODNodeRendererFactorySetEntry
224
225 - (void)dealloc {
226   RELEASE(self->factory);
227   RELEASE(self->namespaceURI);
228   RELEASE(self->tagName);
229   RELEASE(self->qualifier);
230   [super dealloc];
231 }
232
233 - (BOOL)matchesNode:(id)_node {
234   if (self->namespaceURI) {
235     if (![self->namespaceURI isEqualToString:[_node namespaceURI]])
236       return NO;
237   }
238   if (self->tagName) {
239     if (![self->tagName isEqualToString:[_node tagName]])
240       return NO;
241   }
242   if (self->qualifier) {
243     if (![(id<EOQualifierEvaluation>)self->qualifier evaluateWithObject:_node])
244       return NO;
245   }
246   
247   return YES;
248 }
249
250 - (ODNodeRendererFactory *)nodeRendererFactory {
251   return self->factory;
252 }
253
254 @end /* _ODNodeRendererFactorySetEntry */