From: helge Date: Mon, 13 Sep 2004 02:36:42 +0000 (+0000) Subject: enhanced wrapper template build to allow "wrapperless" wod templates X-Git-Url: https://err.no/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=7d3dfbe4d022eaa9a882d920320f8afda67c4414;p=sope enhanced wrapper template build to allow "wrapperless" wod templates fixed and cleanups in the resource managers git-svn-id: http://svn.opengroupware.org/SOPE/trunk@132 e4a50df8-12e2-0310-a44c-efbce7f8a7e3 --- diff --git a/sope-appserver/NGObjWeb/ChangeLog b/sope-appserver/NGObjWeb/ChangeLog index a04291ab..919bea0e 100644 --- a/sope-appserver/NGObjWeb/ChangeLog +++ b/sope-appserver/NGObjWeb/ChangeLog @@ -1,3 +1,15 @@ +2004-09-13 Helge Hess + + * v4.3.37 + + * Templates/WOWrapperTemplateBuilder.m: added ability to load wod + templates without a .wo wrapper (but from an arbitary path). You need + to pass in the .html file of the template to enable that. Used in OGo + for FHS support. + + * OWResourceManager.m: do not look for templates in WebServerResources, + major cleanups in resource lookup code + 2004-09-11 Marcus Mueller * GNUmakefile.preamble: minor changes for inline compilation with diff --git a/sope-appserver/NGObjWeb/NGObjWeb/OWResourceManager.h b/sope-appserver/NGObjWeb/NGObjWeb/OWResourceManager.h index 0818f546..d323d12b 100644 --- a/sope-appserver/NGObjWeb/NGObjWeb/OWResourceManager.h +++ b/sope-appserver/NGObjWeb/NGObjWeb/OWResourceManager.h @@ -18,7 +18,6 @@ Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -// $Id$ #ifndef __NGObjWeb_OWResourceManager_H__ #define __NGObjWeb_OWResourceManager_H__ @@ -48,6 +47,8 @@ NSMapTable *keyedResources; } +- (BOOL)shouldLookupResourceInWebServerResources:(NSString *)_name; + - (NSString *)pathForResourceNamed:(NSString *)_name inFramework:(NSString *)_frameworkName languages:(NSArray *)_languages; @@ -97,6 +98,9 @@ inFramework:(NSString *)_framework languages:(NSArray *)_langs; +- (NSString *)pathToComponentNamed:(NSString *)_name + inFramework:(NSString *)_framework; + - (void)setCachingEnabled:(BOOL)_flag; - (BOOL)isCachingEnabled; diff --git a/sope-appserver/NGObjWeb/OWResourceManager.m b/sope-appserver/NGObjWeb/OWResourceManager.m index 7486fd8e..90a9260b 100644 --- a/sope-appserver/NGObjWeb/OWResourceManager.m +++ b/sope-appserver/NGObjWeb/OWResourceManager.m @@ -18,7 +18,6 @@ Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -// $Id$ // ATTENTION: this class is for OGo legacy, so that WO compatibility changes // to WOResourceManager do not break OGo. @@ -42,6 +41,9 @@ This methods works in three steps: 1. discovery of files associated with the component + - (WOComponentDefinition *)definitionForComponent:(id)_name + inFramework:(NSString *)_framework + languages:(NSArray *)_languages 2. creation of a proper WOComponentDefinition, which is some kind of 'blueprint' or 'class' for components @@ -58,6 +60,9 @@ - (WOComponentDefinition *)definitionForComponent:(id)_name inFramework:(NSString *)_frameworkName languages:(NSArray *)_languages + + Notably in WO 5.3 the WOResourceManager doesn't seem to handle components + anymore. */ /* @@ -83,10 +88,11 @@ return 4; } -static Class UrlClass = Nil; -static NSString *resourcePrefix = @""; -static NSString *rapidTurnAroundPath = nil; -static NSNull *null = nil; +static NSFileManager *fm = nil; +static Class UrlClass = Nil; +static NSString *resourcePrefix = @""; +static NSString *rapidTurnAroundPath = nil; +static NSNull *null = nil; static BOOL debugOn = NO; static BOOL debugComponentLookup = NO; static BOOL debugResourceLookup = NO; @@ -98,7 +104,8 @@ static BOOL genMissingResourceLinks = NO; NSDictionary *defs; if (isInitialized) return; isInitialized = YES; - + + fm = [[NSFileManager defaultManager] retain]; null = [[NSNull null] retain]; UrlClass = [NSURL class]; @@ -322,14 +329,72 @@ _pathExists(OWResourceManager *self, NSFileManager *fm, NSString *path) return self->w3resources; } +- (NSString *)_lookupResourceNamed:(NSString *)_name inPath:(NSString *)_path + inFramework:(NSString *)_frameworkName + languages:(NSArray *)_languages +{ + unsigned i, langCount; + NSString *resource; + + if (_path == nil) + return nil; + + // first check Language.lproj in WebServerResources + for (i = 0, langCount = [_languages count]; i < langCount; i++) { + NSString *langPath; + + langPath = [_languages objectAtIndex:i]; + langPath = [langPath stringByAppendingPathExtension:@"lproj"]; + langPath = [_path stringByAppendingPathComponent:langPath]; + + if (!_pathExists(self, fm, langPath)) { + if (debugResourceLookup) { + [self logWithFormat: + @" no language lproj for '%@' in path: %@", + [_languages objectAtIndex:i], _path]; + } + continue; + } + + resource = [langPath stringByAppendingPathComponent:_name]; + + if (_pathExists(self, fm, resource)) { + if (debugResourceLookup) + [self logWithFormat:@" found path: %@", resource]; + return resource; + } + else if (debugResourceLookup) + [self logWithFormat:@" not found in path: %@", resource]; + } + + /* next check in resources path (WebServerResources or Resources) itself */ + resource = [_path stringByAppendingPathComponent:_name]; + if (debugResourceLookup) + [self logWithFormat:@" check for flat path: %@", resource]; + if (_pathExists(self, fm, resource)) + return resource; + + return nil; +} + +- (BOOL)shouldLookupResourceInWebServerResources:(NSString *)_name { + if ([_name hasSuffix:@".wox"]) return NO; + if ([_name hasSuffix:@".wo"]) return NO; + return YES; +} + - (NSString *)pathForResourceNamed:(NSString *)_name inFramework:(NSString *)_frameworkName languages:(NSArray *)_languages { + /* + Note: at least in the case of OGo component lookups the framework name is + properly filled with the OGo bundle path on lookup, so no + NGBundleManager query is necessary. + */ NSFileManager *fm; NSString *resource = nil; unsigned langCount; - NSString *w3rp, *rp; if (debugResourceLookup) { [self logWithFormat:@"lookup '%@' bundle=%@ languages=%@", @@ -338,71 +403,22 @@ _pathExists(OWResourceManager *self, NSFileManager *fm, NSString *path) fm = [self fileManager]; langCount = [_languages count]; + + /* now check in webserver resources path */ - if ((w3rp = [self webServerResourcesPath])) { - NSString *langPath = nil; - unsigned i; - - // first check Language.lproj in WebServerResources - for (i = 0; i < langCount; i++) { - langPath = [_languages objectAtIndex:i]; - langPath = [langPath stringByAppendingPathExtension:@"lproj"]; - langPath = [w3rp stringByAppendingPathComponent:langPath]; - - if (!_pathExists(self, fm, langPath)) { - if (debugResourceLookup) { - [self logWithFormat: - @" no language project for '%@' in WebServerResources: %@", - [_languages objectAtIndex:i],resource]; - } - continue; - } - - resource = [langPath stringByAppendingPathComponent:_name]; - - if (debugResourceLookup) - [self logWithFormat:@" check in WebServerResources: %@", resource]; - if (_pathExists(self, fm, resource)) - return resource; - } - - /* next check in WebServerResources itself */ - resource = [w3rp stringByAppendingPathComponent:_name]; - if (debugResourceLookup) - [self logWithFormat:@" check in WebServerResources-flat: %@", resource]; - if (_pathExists(self, fm, resource)) - return resource; + if ([self shouldLookupResourceInWebServerResources:_name]) { + resource = [self _lookupResourceNamed:_name + inPath:[self webServerResourcesPath] + inFramework:_frameworkName languages:_languages]; + if (resource != nil) return resource; } - if ((rp = [self resourcesPathForFramework:_frameworkName])) { - NSString *langPath = nil; - unsigned i; - - if (debugResourceLookup) [self logWithFormat:@" path %@", rp]; - - // first check Language.lproj in Resources - for (i = 0; i < langCount; i++) { - langPath = [_languages objectAtIndex:i]; - langPath = [langPath stringByAppendingPathExtension:@"lproj"]; - langPath = [rp stringByAppendingPathComponent:langPath]; - - if (_pathExists(self, fm, langPath)) { - resource = [langPath stringByAppendingPathComponent:_name]; + /* now check in regular resources path */ - if (debugResourceLookup) - [self logWithFormat:@" check in Resources: %@", resource]; - if (_pathExists(self, fm, resource)) - return resource; - } - } - - // next check in Resources itself - resource = [rp stringByAppendingPathComponent:_name]; - if (debugResourceLookup) - [self logWithFormat:@" check in Resources-flat: %@", resource]; - if (_pathExists(self, fm, resource)) - return resource; - } + resource = [self _lookupResourceNamed:_name + inPath:[self resourcesPathForFramework:_frameworkName] + inFramework:_frameworkName languages:_languages]; + if (resource != nil) return resource; /* and last check in the application directory */ if (_pathExists(self, fm, self->base)) { @@ -587,6 +603,7 @@ _pathExists(OWResourceManager *self, NSFileManager *fm, NSString *path) inFramework:(NSString *)_framework { /* search for component wrapper .. */ + // TODO: shouldn't we used that for WOx as well? NSEnumerator *e; NSString *ext; @@ -608,11 +625,11 @@ _pathExists(OWResourceManager *self, NSFileManager *fm, NSString *path) NSString *path; specName = [_name stringByAppendingPathExtension:ext]; - + path = [self pathForResourceNamed:specName inFramework:_framework languages:nil]; - if (path) return path; + if (path != nil) return path; } return nil; } @@ -847,10 +864,23 @@ _pathExists(OWResourceManager *self, NSFileManager *fm, NSString *path) return nil; /* no lproj containing templates was found */ } +- (NSString *)defaultFrameworkForComponentNamed:(NSString *)_name { + Class clazz; + + if (rapidTurnAroundPath != nil) + return rapidTurnAroundPath; + + if ((clazz = NSClassFromString(_name)) == nil) + return nil; + + return [[NSBundle bundleForClass:clazz] bundlePath]; +} + - (WOComponentDefinition *)definitionForComponent:(id)_name inFramework:(NSString *)_framework languages:(NSArray *)_languages { + /* this is the primary method for finding a definition */ // TODO: this method is too large WOApplication *app; NSFileManager *fm = nil; @@ -874,21 +904,16 @@ _pathExists(OWResourceManager *self, NSFileManager *fm, NSString *path) else { NSString *path; - if (_framework == nil && _name != nil) { - Class clazz; - - /* - Note: this is a bit of a hack ..., actually this method should never - be called without a framework and pages shouldn't be instantiated - without specifying their framework. - But for legacy reasons this needs to be done and seems to work without - problems. It is required for loading components from bundles. - */ - if ((_framework = rapidTurnAroundPath) == nil) { - if ((clazz = NSClassFromString(_name))) - _framework = [[NSBundle bundleForClass:clazz] bundlePath]; - } - } + /* + Note: this is a bit of a hack ..., actually this method should never + be called without a framework and pages shouldn't be instantiated + without specifying their framework. + But for legacy reasons this needs to be done and seems to work + without problems. It is required for loading components from + bundles. + */ + if (_framework == nil && _name != nil) + _framework = [self defaultFrameworkForComponentNamed:_name]; if (debugComponentLookup) { [self logWithFormat:@"lookup: component '%@' in framework '%@'", @@ -897,6 +922,7 @@ _pathExists(OWResourceManager *self, NSFileManager *fm, NSString *path) /* look for .wox component */ + // TODO: why don't we use -pathForComponentNamed: here? path = [self pathForResourceNamed: [self resourceNameForComponentNamed:_name] inFramework:_framework @@ -1050,15 +1076,18 @@ _pathExists(OWResourceManager *self, NSFileManager *fm, NSString *path) return [self definitionForComponent:_name inFramework:nil languages:_langs]; } +/* caching */ + - (WOComponentDefinition *)__definitionForComponent:(id)_name languages:(NSArray *)_languages { + // TODO: this should add the framework parameter and maybe a context WOComponentDefinition *cdef; /* look into cache */ cdef = [self _cachedDefinitionForComponent:_name languages:_languages]; - if (cdef) { + if (cdef != nil) { if (cdef == (id)null) /* component does not exist */ return nil; @@ -1077,6 +1106,8 @@ _pathExists(OWResourceManager *self, NSFileManager *fm, NSString *path) return [self _cacheDefinition:cdef forComponent:_name languages:_languages]; } +/* primary call-in's */ + - (WOElement *)templateWithName:(NSString *)_name languages:(NSArray *)_languages { @@ -1102,7 +1133,7 @@ _pathExists(OWResourceManager *self, NSFileManager *fm, NSString *path) pool = [[NSAutoreleasePool alloc] init]; { cdef = [self __definitionForComponent:_name languages:_languages]; - if (cdef) { + if (cdef != nil) { component = [cdef instantiateWithResourceManager:(WOResourceManager *)self languages:_languages]; @@ -1114,14 +1145,6 @@ _pathExists(OWResourceManager *self, NSFileManager *fm, NSString *path) return [component autorelease]; } -/* description */ - -- (NSString *)description { - return [NSString stringWithFormat:@"<%@[0x%08X]: path=%@>", - [self class], self, self->base]; - -} - /* KeyedData */ - (void)setData:(NSData *)_data @@ -1190,4 +1213,12 @@ _pathExists(OWResourceManager *self, NSFileManager *fm, NSString *path) [self unlock]; } +/* description */ + +- (NSString *)description { + return [NSString stringWithFormat:@"<%@[0x%08X]: path=%@>", + [self class], self, self->base]; + +} + @end /* OWResourceManager */ diff --git a/sope-appserver/NGObjWeb/TODO b/sope-appserver/NGObjWeb/TODO index 092706e6..2c835acf 100644 --- a/sope-appserver/NGObjWeb/TODO +++ b/sope-appserver/NGObjWeb/TODO @@ -11,6 +11,10 @@ which start with: +- implement WOMultipartIterator like in WO 5.3, would be useful for the + WOSimpleHTTPParser + - also: WOMultipartIterator.WOFormData + Dynamic Elements ================ - none missing? diff --git a/sope-appserver/NGObjWeb/Templates/WOWrapperTemplateBuilder.m b/sope-appserver/NGObjWeb/Templates/WOWrapperTemplateBuilder.m index 0cb83705..333df3ff 100644 --- a/sope-appserver/NGObjWeb/Templates/WOWrapperTemplateBuilder.m +++ b/sope-appserver/NGObjWeb/Templates/WOWrapperTemplateBuilder.m @@ -62,6 +62,7 @@ static Class StrClass = Nil; @implementation WOWrapperTemplateBuilder +static BOOL debugOn = NO; static BOOL logExtraAssociations = NO; static BOOL logScriptAdditions = NO; static NSStringEncoding parserEncoding; @@ -192,6 +193,38 @@ static NSStringEncoding parserEncoding; return newException; } +- (NSStringEncoding)encodingForString:(NSString *)_enc { + NSStringEncoding encoding; + + encoding = 0; + + if ([_enc isEqualToString:@"NSASCIIStringEncoding"]) + encoding = NSASCIIStringEncoding; + else if ([_enc isEqualToString:@"NSNEXTSTEPStringEncoding"]) + encoding = NSNEXTSTEPStringEncoding; + else if ([_enc isEqualToString:@"NSUTF8StringEncoding"]) + encoding = NSUTF8StringEncoding; + else if ([_enc isEqualToString:@"NSISOLatin1StringEncoding"]) + encoding = NSISOLatin1StringEncoding; + else if ([_enc isEqualToString:@"NSISOLatin2StringEncoding"]) + encoding = NSISOLatin2StringEncoding; + else if ([_enc isEqualToString:@"NSUnicodeStringEncoding"]) + encoding = NSUnicodeStringEncoding; + else if ([_enc length] == 0) + ; // keep platform encoding +#if LIB_FOUNDATION_LIBRARY + else if ([_enc isEqualToString:@"NSISOLatin9StringEncoding"]) + encoding = NSISOLatin9StringEncoding; + else if ([_enc isEqualToString:@"NSWinLatin1StringEncoding"]) + encoding = NSWinLatin1StringEncoding; +#endif +#if NeXT_Foundation_LIBRARY || COCOA_Foundation_LIBRARY + else + encoding = [NSString stringEncodingForEncodingNamed:_enc]; +#endif + return encoding; +} + - (WOTemplate *)buildTemplateAtURL:(NSURL *)_url { static NSData *emptyData = nil; NSFileManager *fm; @@ -219,14 +252,18 @@ static NSStringEncoding parserEncoding; return nil; } + /* setup local and common objects */ + if (emptyData == nil) emptyData = [[NSData alloc] init]; - fm = [NSFileManager defaultManager]; - path = [_url path]; - if (self->definitions == nil) self->definitions = [[NSMutableDictionary alloc] initWithCapacity:64]; + + /* process pathes */ + + fm = [NSFileManager defaultManager]; + path = [_url path]; tmpPath = [path lastPathComponent]; withLanguage = [[tmpPath pathExtension] isEqualToString:@"lproj"]; @@ -243,6 +280,17 @@ static NSStringEncoding parserEncoding; tmpPath = [path stringByDeletingLastPathComponent]; name = [[tmpPath lastPathComponent] stringByDeletingPathExtension]; } + else if ([path hasSuffix:@".html"]) { + /* + If we pass in the .html, this basically means that the .html and .wod + are not inside a wrapper but in some arbitary directory. + This is used in OGo to support FHS location in a Unix-like way (the + templates live in /usr/share/ogo/templates/xyz.html and xyz.wod). + */ + name = [[path lastPathComponent] stringByDeletingPathExtension]; + path = [path stringByDeletingLastPathComponent]; + if (debugOn) [self logWithFormat:@"CHECK: %@", path]; + } else { /* eg /a/b/c/a.wo/a.html */ name = [[path lastPathComponent] stringByDeletingPathExtension]; @@ -251,6 +299,8 @@ static NSStringEncoding parserEncoding; tmpPath = [name stringByAppendingPathExtension:@"wod"]; tmpPath = [path stringByAppendingPathComponent:tmpPath]; wodFile = [NSData dataWithContentsOfFile:tmpPath]; + if (debugOn) + [self logWithFormat:@"CHECK: %@ + %@ => %@", path, name, tmpPath]; tmpPath = [name stringByAppendingPathExtension:@"html"]; tmpPath = [path stringByAppendingPathComponent:tmpPath]; @@ -309,38 +359,10 @@ static NSStringEncoding parserEncoding; /* process string encoding */ encoding = parserEncoding; - if ((tmp = [wooFile objectForKey:@"encoding"])) { + if ((tmp = [wooFile objectForKey:@"encoding"]) != nil) { // TODO: move to an NSString category, isn't there a method for this in // Foundation?! - - encoding = 0; - - if ([tmp isEqualToString:@"NSASCIIStringEncoding"]) - encoding = NSASCIIStringEncoding; - else if ([tmp isEqualToString:@"NSNEXTSTEPStringEncoding"]) - encoding = NSNEXTSTEPStringEncoding; - else if ([tmp isEqualToString:@"NSUTF8StringEncoding"]) - encoding = NSUTF8StringEncoding; - else if ([tmp isEqualToString:@"NSISOLatin1StringEncoding"]) - encoding = NSISOLatin1StringEncoding; - else if ([tmp isEqualToString:@"NSISOLatin2StringEncoding"]) - encoding = NSISOLatin2StringEncoding; - else if ([tmp isEqualToString:@"NSUnicodeStringEncoding"]) - encoding = NSUnicodeStringEncoding; - else if ([tmp length] == 0) - ; // keep platform encoding -#if LIB_FOUNDATION_LIBRARY - else if ([tmp isEqualToString:@"NSISOLatin9StringEncoding"]) - encoding = NSISOLatin9StringEncoding; - else if ([tmp isEqualToString:@"NSWinLatin1StringEncoding"]) - encoding = NSWinLatin1StringEncoding; -#endif -#if NeXT_Foundation_LIBRARY || COCOA_Foundation_LIBRARY - else - encoding = [NSString stringEncodingForEncodingNamed:tmp]; -#endif - - if (encoding == 0) { + if ((encoding = [self encodingForString:tmp]) == 0) { [self logWithFormat: @"ERROR(%s): cannot deal with template encoding: '%@'", __PRETTY_FUNCTION__, tmp]; diff --git a/sope-appserver/NGObjWeb/Version b/sope-appserver/NGObjWeb/Version index 3e663142..89f877e1 100644 --- a/sope-appserver/NGObjWeb/Version +++ b/sope-appserver/NGObjWeb/Version @@ -1,6 +1,6 @@ # version file -SUBMINOR_VERSION:=36 +SUBMINOR_VERSION:=37 # v4.2.413 requires libSaxObjC v4.2.33 # v4.2.341 requires libNGExtensions v4.2.77 diff --git a/sope-appserver/NGObjWeb/WOApplication+defaults.m b/sope-appserver/NGObjWeb/WOApplication+defaults.m index 2a5f8e80..17057ac3 100644 --- a/sope-appserver/NGObjWeb/WOApplication+defaults.m +++ b/sope-appserver/NGObjWeb/WOApplication+defaults.m @@ -18,7 +18,6 @@ Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -// $Id$ #include #include "common.h" diff --git a/sope-appserver/NGObjWeb/WOComponentDefinition.m b/sope-appserver/NGObjWeb/WOComponentDefinition.m index 4a6e354a..7da4e69a 100644 --- a/sope-appserver/NGObjWeb/WOComponentDefinition.m +++ b/sope-appserver/NGObjWeb/WOComponentDefinition.m @@ -121,7 +121,7 @@ static NSNumber *noNum = nil; languages:_languages bindings:[childInfo bindings]]; - if (child) { + if (child != nil) { if (childComponents == nil) childComponents = [NSMutableDictionary dictionaryWithCapacity:16]; diff --git a/sope-appserver/NGObjWeb/WOResourceManager.m b/sope-appserver/NGObjWeb/WOResourceManager.m index d53cc2b3..32e73780 100644 --- a/sope-appserver/NGObjWeb/WOResourceManager.m +++ b/sope-appserver/NGObjWeb/WOResourceManager.m @@ -202,6 +202,11 @@ _pathExists(WOResourceManager *self, NSFileManager *fm, NSString *path) - (BOOL)isDebuggingEnabled { return debugOn; } +- (NSString *)loggingPrefix { + unsigned char buf[32]; + sprintf(buf, "[wo-rm-0x%08X]", (unsigned)self); + return [NSString stringWithCString:buf]; +} /* path methods */ @@ -595,6 +600,7 @@ _pathExists(WOResourceManager *self, NSFileManager *fm, NSString *path) inFramework:(NSString *)_framework { /* search for component wrapper .. */ + // TODO: shouldn't we used that for WOx as well? NSEnumerator *e; NSString *ext; @@ -717,61 +723,54 @@ _pathExists(WOResourceManager *self, NSFileManager *fm, NSString *path) return [_name stringByAppendingPathExtension:@"wox"]; } -- (WOComponentDefinition *)definitionForComponent:(id)_name - inFramework:(NSString *)_framework +/* create component definition */ + +- (void)_getComponentURL:(NSURL **)url_ andName:(NSString **)name_ + forNameOrURL:(id)_nameOrURL inFramework:(NSString *)_framework languages:(NSArray *)_languages { - WOApplication *app; - NSFileManager *fm = nil; - NSEnumerator *languages = nil; - NSString *language = nil; - WOComponentDefinition *cdef = nil; - NSString *sname = nil; - NSURL *componentURL; - NSURL *appUrl; - BOOL doesCache, isDir; + NSString *path; - app = [WOApplication application]; - doesCache = [app isCachingEnabled]; + if ([_nameOrURL isKindOfClass:UrlClass]) { + // TODO: where is this used currently? It probably was required for forms, + // but might not be anymore? + *url_ = _nameOrURL; + *name_ = [*url_ path]; + if (debugComponentLookup) + [self debugWithFormat:@"using URL %@ for component %@", *url_, *name_]; + return; + } - /* lookup component path */ + /* the _nameOrURL is a string containing the component name */ - if ([_name isKindOfClass:UrlClass]) { - componentURL = _name; - _name = [componentURL path]; - if (debugComponentLookup) { - [self debugWithFormat:@"using URL %@ for component %@", - componentURL, _name]; - } - } - else { - NSString *path; - - if (_framework == nil && _name != nil) { - Class clazz; + *name_ = _nameOrURL; + + if (_framework == nil && _nameOrURL != nil) { + Class clazz; - /* - Note: this is a bit of a hack ..., actually this method should never - be called without a framework and pages shouldn't be instantiated - without specifying their framework. - But for legacy reasons this needs to be done and seems to work without - problems. It is required for loading components from bundles. - */ - if ((_framework = rapidTurnAroundPath) == nil) { - if ((clazz = NSClassFromString(_name))) - _framework = [[NSBundle bundleForClass:clazz] bundlePath]; - } - } - - if (debugComponentLookup) { - [self logWithFormat:@"component '%@' in framework '%@'", - _name, _framework]; + /* + Note: this is a bit of a hack ..., actually this method should never + be called without a framework and pages shouldn't be instantiated + without specifying their framework. + But for legacy reasons this needs to be done and seems to work without + problems. It is required for loading components from bundles. + */ + if ((_framework = rapidTurnAroundPath) == nil) { + if ((clazz = NSClassFromString(_nameOrURL))) + _framework = [[NSBundle bundleForClass:clazz] bundlePath]; } + } + + if (debugComponentLookup) { + [self logWithFormat:@"component '%@' in framework '%@'", + _nameOrURL, _framework]; + } + /* look for .wox component */ path = [self pathForResourceNamed: - [self resourceNameForComponentNamed:_name] + [self resourceNameForComponentNamed:*name_] inFramework:_framework languages:_languages]; @@ -781,7 +780,7 @@ _pathExists(WOResourceManager *self, NSFileManager *fm, NSString *path) /* look for .wo component */ if ([path length] == 0) { - path = [self pathToComponentNamed:_name + path = [self pathToComponentNamed:*name_ inFramework:_framework languages:_languages]; if (debugComponentLookup) @@ -790,97 +789,96 @@ _pathExists(WOResourceManager *self, NSFileManager *fm, NSString *path) /* make URL from path */ - componentURL = ([path length] > 0) + *url_ = ([path length] > 0) ? [[[UrlClass alloc] initFileURLWithPath:path] autorelease] : nil; - } - - if (debugComponentLookup) { - [self logWithFormat:@" component='%@' in framework='%@': url='%@'", - _name, _framework, componentURL]; - } - - appUrl = [app baseURL]; - - /* check whether it's a 'template-less' component ... */ - - if (componentURL == nil) { - /* did not find component wrapper ! */ - [app debugWithFormat:@" component '%@' has no template !", _name]; - - cdef = [self _definitionForPathlessComponent:_name languages:_languages]; - return cdef; - } - - fm = [self fileManager]; - - /* ensure that the component exists */ +} - if ([componentURL isFileURL]) { - NSString *componentPath; +- (WOComponentDefinition *)definitionForFileURL:(NSURL *)componentURL + componentName:(NSString *)_name inFramework:(NSString *)_framework + languages:(NSArray *)_languages +{ + NSFileManager *fm; + NSString *componentPath; + BOOL doesCache, isDir; + NSEnumerator *languages; + NSString *language; + NSString *sname = nil; + NSURL *appUrl; - componentPath = [componentURL path]; + fm = [self fileManager]; + componentPath = [componentURL path]; + doesCache = [[WOApplication application] isCachingEnabled]; - if (![fm fileExistsAtPath:componentPath isDirectory:&isDir]) { - [[WOApplication application] + if (![fm fileExistsAtPath:componentPath isDirectory:&isDir]) { + [[WOApplication application] debugWithFormat: @"%s: did not find component '%@' at path '%@' !", __PRETTY_FUNCTION__, _name, componentPath]; - return cdef; - } + return nil; + } - /* if the component spec is a directory (eg a .wo), scan inside for stuff */ - - if (isDir) { - languages = [_languages objectEnumerator]; - - while ((language = [languages nextObject])) { - NSString *compoundKey = nil; - NSString *languagePath = nil; - BOOL isDirectory = NO; + /* if the component spec is a directory (eg a .wo), scan inside for stuff*/ + + if (!isDir) + return nil; + + appUrl = [[WOApplication application] baseURL]; + languages = [_languages objectEnumerator]; + while ((language = [languages nextObject])) { + WOComponentDefinition *cdef; + NSString *compoundKey = nil; + NSString *languagePath = nil; + NSString *baseUrl = nil; + BOOL isDirectory = NO; - if (sname == nil) sname = [_name stringByAppendingString:@"\t"]; - compoundKey = [sname stringByAppendingString:language]; + if (sname == nil) sname = [_name stringByAppendingString:@"\t"]; + compoundKey = [sname stringByAppendingString:language]; - if (doesCache) { - cdef = NSMapGet(self->componentDefinitions, compoundKey); - - if (cdef == (id)null) - /* resource does not exist */ - continue; + if (doesCache) { + cdef = NSMapGet(self->componentDefinitions, compoundKey); + + if (cdef == (id)null) + /* resource does not exist */ + continue; - [cdef touch]; - if (cdef) return cdef; // found definition in cache - } - - /* take a look into the file system */ - languagePath = [language stringByAppendingPathExtension:@"lproj"]; - languagePath = + [cdef touch]; + if (cdef != nil) return cdef; // found definition in cache + } + + /* take a look into the file system */ + languagePath = [language stringByAppendingPathExtension:@"lproj"]; + languagePath = [componentPath stringByAppendingPathComponent:languagePath]; - if ([fm fileExistsAtPath:languagePath isDirectory:&isDirectory]) { - NSString *baseUrl = nil; - - if (!isDirectory) { - NSLog(@"WARNING(%s): language entry %@ is not a directory !", + if (![fm fileExistsAtPath:languagePath isDirectory:&isDirectory]) { + if (doesCache) { + /* register null in cache, so that we know it's non-existent */ + NSMapInsert(self->componentDefinitions, compoundKey, null); + } + continue; + } + + if (!isDirectory) { + NSLog(@"WARNING(%s): language entry %@ is not a directory !", __PRETTY_FUNCTION__, languagePath); if (doesCache && (compoundKey != nil)) { // register null in cache, so that we know it's non-existent NSMapInsert(self->componentDefinitions, compoundKey, null); } continue; - } + } - baseUrl = [NSString stringWithFormat:@"%@/%@.lproj/%@.wo", + baseUrl = [NSString stringWithFormat:@"%@/%@.lproj/%@.wo", [appUrl absoluteString], language, _name]; - /* found appropriate language project */ - cdef = [self _definitionWithName:_name + /* found appropriate language project */ + cdef = [self _definitionWithName:_name path:languagePath baseURL:[NSURL URLWithString:baseUrl] frameworkName:nil]; - if (cdef == nil) { + if (cdef == nil) { NSLog(@"WARNING(%s): could not load component definition of " @"'%@' from language project: %@", __PRETTY_FUNCTION__, _name, languagePath); @@ -889,28 +887,73 @@ _pathExists(WOResourceManager *self, NSFileManager *fm, NSString *path) NSMapInsert(self->componentDefinitions, compoundKey, null); } continue; - } + } - if (doesCache && (compoundKey != nil)) { + if (doesCache && (compoundKey != nil)) { // register in cache NSMapInsert(self->componentDefinitions, compoundKey, cdef); [cdef release]; - } - else { + } + else { // don't register in cache cdef = [cdef autorelease]; - } - - return cdef; - } - else { - if (doesCache) { - // register null in cache, so that we know it's non-existent - NSMapInsert(self->componentDefinitions, compoundKey, null); - } - } - } } + + return cdef; + } + return nil; +} + +- (WOComponentDefinition *)definitionForComponent:(id)_name + inFramework:(NSString *)_framework + languages:(NSArray *)_languages +{ + // TODO: this method is definitely too big! => refacture + WOApplication *app; + NSFileManager *fm = nil; + WOComponentDefinition *cdef = nil; + NSURL *componentURL; + NSURL *appUrl; + BOOL doesCache; + + app = [WOApplication application]; + doesCache = [app isCachingEnabled]; + + /* lookup component path */ + + [self _getComponentURL:&componentURL andName:&_name + forNameOrURL:_name inFramework:nil languages:nil]; + + if (debugComponentLookup) { + [self logWithFormat:@" component='%@' in framework='%@': url='%@'", + _name, _framework, componentURL]; + } + + appUrl = [app baseURL]; + + /* check whether it's a 'template-less' component ... */ + + if (componentURL == nil) { + /* did not find component wrapper ! */ + [app debugWithFormat:@" component '%@' has no template !", _name]; + + cdef = [self _definitionForPathlessComponent:_name languages:_languages]; + return cdef; + } + + fm = [self fileManager]; + + /* ensure that the component exists */ + + if ([componentURL isFileURL]) { + WOComponentDefinition *cdef; + + cdef = [self definitionForFileURL:componentURL componentName:_name + inFramework:_framework languages:_languages]; + if (cdef != nil && ![cdef isNotNull]) + return nil; + else if (cdef != nil) + return cdef; } /* look flat */ @@ -966,22 +1009,30 @@ _pathExists(WOResourceManager *self, NSFileManager *fm, NSString *path) - (WOComponentDefinition *)definitionForComponent:(id)_name languages:(NSArray *)_langs { + // TODO: who uses that? Probably should be deprecated? return [self definitionForComponent:_name inFramework:nil languages:_langs]; } - (WOComponentDefinition *)__definitionForComponent:(id)_name languages:(NSArray *)_languages { + /* + First check whether the cdef is cached, otherwise create a new one. + + This method is used by the higher level methods and just implements the + cache control. + The definition itself is created by definitionForComponent:languages:. + */ WOComponentDefinition *cdef; /* look into cache */ cdef = [self _cachedDefinitionForComponent:_name languages:_languages]; - if (cdef) { + if (cdef != nil) { if (cdef == (id)null) /* component does not exist */ return nil; - + if ([cdef respondsToSelector:@selector(touch)]) [cdef touch]; return cdef; @@ -1007,24 +1058,22 @@ _pathExists(WOResourceManager *self, NSFileManager *fm, NSString *path) return (WOElement *)[cdef template]; } -- (WOComponent *)pageWithName:(NSString *)_name - languages:(NSArray *)_languages -{ +- (WOComponent *)pageWithName:(NSString *)_name languages:(NSArray *)_langs { /* TODO: this appears to be deprecated since the WOComponent initializer - is now -initWithContext: and we have no context here ... + is now -initWithContext: and we have no context over here ... */ - NSAutoreleasePool *pool = nil; - WOComponentDefinition *cdef = nil; + NSAutoreleasePool *pool; + WOComponentDefinition *cdef; WOComponent *component = nil; pool = [[NSAutoreleasePool alloc] init]; { - cdef = [self __definitionForComponent:_name languages:_languages]; - if (cdef) { + cdef = [self __definitionForComponent:_name languages:_langs]; + if (cdef != nil) { + // TODO: document what the resource manager is used for in the cdef component = - [cdef instantiateWithResourceManager:self languages:_languages]; - component = [component retain]; + [[cdef instantiateWithResourceManager:self languages:_langs] retain]; } } [pool release];