libs-gsweb/GSWeb/GSWResourceManager.m
David Wetzel a8eccb4273 * GSWDatabase/WODisplayGroup.m
fix format string and NSArray / NSMutableArray bugs
    * GSWeb/GNUmakefile
    * GSWeb/GSWApplication.h
    * GSWeb/GSWApplication.m
      replace GSWMultiKeyDictionary with GSWDictionary
    * GSWeb/GSWDefaultAdaptor.m
      limit _workerThreadCountMax to 16 for now
    * GSWeb/GSWDeployedBundle.*, GSWResourceManager.*
      replace GSWMultiKeyDictionary with GSWDictionary
    * GSWeb/GSWDictionary
      new class using NSMutableDictionary internally.
    * GSWeb/GSWImageInfo.m
      fix leak
    * GSWeb/GSWRequest.m
      fix leak
    * GSWeb/GSWUtils.m
      fix leak
    * GSWeb/GSWWOCompatibility.h
      remove GSWMultiKeyDictionary
    * GSWeb/GSWWorkerThread.m
      some cleanups but still does not run in MT on FreeBSD.
    * GSWeb/NSString+Trimming.m
      fix leaks
    * Tests/gsweb/GNUmakefile.postamble
    * Tests/gsweb/GNUmakefile.super
    * Tests/gsweb/GSWDictionary/TestInfo
    * Tests/gsweb/GSWDictionary/general.m
      new files
2017-12-25 00:25:03 -05:00

1081 lines
31 KiB
Objective-C

/** GSWResourceManager.m - <title>GSWeb: Class GSWResourceManager</title>
Copyright (C) 1999-2005 Free Software Foundation, Inc.
Written by: Manuel Guesdon <mguesdon@orange-concept.com>
Date: Jan 1999
$Revision$
$Date$
<abstract></abstract>
This file is part of the GNUstep Web Library.
<license>
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Library General Public License for more details.
You should have received a copy of the GNU Library General Public
License along with this library; if not, write to the Free
Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
</license>
**/
#include "config.h"
#include "GSWeb.h"
#include <GNUstepBase/NSObject+GNUstepBase.h>
#include <GNUstepBase/NSString+GNUstepBase.h>
#include "GSWPrivate.h"
static NSString * NONESTR = @"NONE";
static NSString * localNotFoundMarker=@"NOTFOUND";
static NSMutableDictionary * TheStringsTableDictionary = nil;
static NSLock * TheStringsTableLock = nil;
//====================================================================
@implementation GSWResourceManager
GSWProjectBundle* globalAppProjectBundle=nil;
NSDictionary* globalMime=nil;
NSString* globalMimePListPathName=nil;
NSDictionary* localGS2ISOLanguages=nil;
NSDictionary* localISO2GSLanguages=nil;
NSString* globalLanguagesPListPathName=nil;
NSMutableDictionary *globalPathCache = nil;
NSMutableDictionary *globalURLCache = nil;
//--------------------------------------------------------------------
+(void)initialize
{
if (self==[GSWResourceManager class])
{
NSBundle* mainBundle=[GSWApplication mainBundle];
NSString* bundlePath=[mainBundle bundlePath];
ASSIGN(globalAppProjectBundle,([GSWDeployedBundle bundleWithPath:bundlePath]));
NSAssert(globalAppProjectBundle,@"no globalAppProjectBundle");
globalPathCache = [NSMutableDictionary new];
globalURLCache = [NSMutableDictionary new];
TheStringsTableDictionary = [NSMutableDictionary new];
TheStringsTableLock = [NSLock new];
};
};
-(void) _loadMimeTypes
{
NSBundle* resourceManagerBundle = [NSBundle bundleForClass: [self class]];
globalMimePListPathName=[resourceManagerBundle pathForResource:@"MIME"
ofType:@"plist"];
NSAssert(globalMimePListPathName,@"No resource MIME.plist");
{
NSDictionary* tmpMimeTypes=nil;
NSMutableDictionary* mimeTypes=(NSMutableDictionary*)[NSMutableDictionary dictionary];
tmpMimeTypes=[NSDictionary dictionaryWithContentsOfFile:globalMimePListPathName];
if (tmpMimeTypes)
{
NSEnumerator* enumerator = [tmpMimeTypes keyEnumerator];
id key=nil;
id value=nil;
while ((key = [enumerator nextObject]))
{
value=[tmpMimeTypes objectForKey:key];
NSAssert(value,@"No value");
value=[value lowercaseString];
key=[key lowercaseString];
NSAssert(key,@"No key");
[mimeTypes setObject:value
forKey:key];
};
// NSDebugMLLog(@"resmanager",@"mimeTypes=%@",mimeTypes);
};
ASSIGN(globalMime,[NSDictionary dictionaryWithDictionary:mimeTypes]);
}
}
- (void) _loadLanguages
{
NSBundle* resourceManagerBundle = [NSBundle bundleForClass: [self class]];
globalLanguagesPListPathName=[resourceManagerBundle pathForResource:@"languages"
ofType:@"plist"];
if (!globalLanguagesPListPathName)
globalLanguagesPListPathName=[[NSBundle bundleForClass: [self class]]
pathForResource:@"languages"
ofType:@"plist"];
NSAssert(globalLanguagesPListPathName,@"No resource languages.plist");
{
NSDictionary* tmpLanguages=nil;
NSMutableDictionary* ISO2GS=(NSMutableDictionary*)[NSMutableDictionary dictionary];
NSMutableDictionary* GS2ISO=(NSMutableDictionary*)[NSMutableDictionary dictionary];
tmpLanguages=[NSDictionary dictionaryWithContentsOfFile:globalLanguagesPListPathName];
if (tmpLanguages)
{
NSEnumerator* enumerator = [tmpLanguages keyEnumerator];
id iso=nil;
id gs=nil;
while ((iso = [enumerator nextObject]))
{
gs=[tmpLanguages objectForKey:iso];
NSAssert(gs,@"No gs");
[ISO2GS setObject:gs
forKey:[iso lowercaseString]];
if ([iso length]==2)//No xx-xx
{
[GS2ISO setObject:iso
forKey:[gs lowercaseString]];
};
};
};
ASSIGN(localISO2GSLanguages,[NSDictionary dictionaryWithDictionary:ISO2GS]);
ASSIGN(localGS2ISOLanguages,[NSDictionary dictionaryWithDictionary:GS2ISO]);
}
}
//--------------------------------------------------------------------
-(id)init
{
if ((self=[super init]))
{
if (!globalMime)
{
[self _loadMimeTypes];
[self _loadLanguages];
}
//TODO NSBundle* mainBundle=[NSBundle mainBundle];
NSArray* allFrameworks=[NSBundle allFrameworks];
int i=0;
int allFrameworksCount=[allFrameworks count];
NSString* bundlePath=nil;
NSBundle* bundle=nil;
NSDictionary* infoDictionary=nil;
for(i=0;i<allFrameworksCount;i++)
{
bundle=[allFrameworks objectAtIndex:i];
bundlePath=[bundle bundlePath];
//So what ?
};
_selfLock=[NSRecursiveLock new];
_frameworkProjectBundlesCache=[NSMutableDictionary new];
_appURLs=[NSMutableDictionary new];
_frameworkURLs=[NSMutableDictionary new];
_appPaths=[NSMutableDictionary new];
_frameworkPaths=[GSWDictionary new];
_urlValuedElementsData=[NSMutableDictionary new];
_stringsTablesByFrameworkByLanguageByName=[NSMutableDictionary new];
_stringsTableArraysByFrameworkByLanguageByName=[NSMutableDictionary new];
// [self _initFrameworkProjectBundles];
// _frameworkPathsToFrameworksNames=[NSMutableDictionary new];
allFrameworks=[NSBundle allFrameworks];
allFrameworksCount=[allFrameworks count];
for(i=0;i<allFrameworksCount;i++)
{
bundle=[allFrameworks objectAtIndex:i];
infoDictionary=[bundle infoDictionary];
//So what ?
/*
NSDebugMLLog(@"resmanager",@"****bundlePath=%@",bundlePath);
NSDebugMLLog(@"resmanager",@"****[bundle bundleName]=%@",[bundle bundleName]);
bundlePath=[bundle bundlePath];
if ([bundle bundleName])
[_frameworkPathsToFrameworksNames setObject:[bundle bundleName]
forKey:bundlePath];
*/
};
};
return self;
};
//--------------------------------------------------------------------
-(void)dealloc
{
DESTROY(_frameworkProjectBundlesCache);
DESTROY(_appURLs);
DESTROY(_frameworkURLs);
DESTROY(_appPaths);
DESTROY(_frameworkPaths);
DESTROY(_urlValuedElementsData);
DESTROY(_stringsTablesByFrameworkByLanguageByName);
DESTROY(_stringsTableArraysByFrameworkByLanguageByName);
DESTROY(_frameworkClassPaths);
// DESTROY(_frameworkPathsToFrameworksNames);
DESTROY(_selfLock);
[super dealloc];
};
//--------------------------------------------------------------------
-(NSString*)description
{
NSString* dscr=nil;
[self lock];
NS_DURING
{
dscr=[NSString stringWithFormat:@"<%s %p - _frameworkProjectBundlesCache:%p _appURLs:%@ _frameworkURLs:%@ _appPaths:%@ _frameworkPaths:%@ _urlValuedElementsData:%@ _frameworkClassPaths:%@>",
object_getClassName(self),
(void*)self,
(void*)_frameworkProjectBundlesCache,
_appURLs,
_frameworkURLs,
_appPaths,
_frameworkPaths,
_urlValuedElementsData,
_frameworkClassPaths];
}
NS_HANDLER
{
//TODO
[self unlock];
[localException raise];
}
NS_ENDHANDLER;
[self unlock];
return dscr;
};
//--------------------------------------------------------------------
-(NSString*)pathForResourceNamed:(NSString*)name
inFramework:(NSString*)aFrameworkName
languages:(NSArray*)languages
{
NSString * path = nil;
if ((languages) && ([languages count])) {
NSEnumerator * langEnumer = [languages objectEnumerator];
NSString * currentLang;
while (((currentLang = [langEnumer nextObject])) && (!path)) {
path = [self pathForResourceNamed:name
inFramework:aFrameworkName
language:currentLang];
}
} else {
// no languages
path = [self pathForResourceNamed:name
inFramework:aFrameworkName
language:nil];
}
return path;
}
//--------------------------------------------------------------------
- (NSString*) _cleanPath:(NSString*) oldPath frameworkName:(NSString*) frameworkName
{
// /Library/Frameworks/WOExtensions.framework/Versions/1/Resources/WebServer/back.png
// ->> /WOExtensions/wr/back.png
// /Users/dave/dev/gsweb/trunk/Testing/DynamicElements/DynamicElements.gswa/Contents/Resources/WebServer/testpic.jpg
// ->> /wr/testpic.jpg
NSString * newPath = nil;
NSRange range = [oldPath rangeOfString:@"Resources/WebServer"
options:NSBackwardsSearch];
if (range.location == NSNotFound) {
if (([oldPath hasSuffix:@".wo"] == NO)) {
return nil;
}
} else {
newPath = [oldPath substringFromIndex: range.location+range.length];
}
if (!frameworkName) {
return newPath;
}
return [NSString stringWithFormat:@"/%@/wr%@",frameworkName, newPath];
}
/*
Returns the URL for a resource name.
The URL returned is of the following form:
/WebObjects/MyApp.woa/0/wr/English.lproj/name
/WebObjects/MyApp.woa/0/wr/testpic.jpg
/WebObjects/MyApp.woa/0/wr/MyFramework/wr/English.lproj/name
TODO: test with true dynamic data in URLs
*/
-(NSString*)urlForResourceNamed:(NSString*)name
inFramework:(NSString*)aFrameworkName
languages:(NSArray*)languages
request:(GSWRequest*)request
{
NSString * url=nil;
//It's not a complete WO implementation: WO use WODeployedBundle instead of NSBundle
if ([request isUsingWebServer])
{
if ([languages count]>0)
{
NSEnumerator * langEnumer = [languages objectEnumerator];
NSString * currentLang= nil;
while (((currentLang = [langEnumer nextObject])) && url==nil)
{
url = [self urlForResourceNamed:name
inFramework:aFrameworkName
language:currentLang];
}
}
if (url==nil)
{
// no languages or url not found
url = [self urlForResourceNamed:name
inFramework:aFrameworkName
language:nil];
}
}
else
{
NSString * path=nil;
if ([languages count]>0)
{
NSEnumerator * langEnumer = [languages objectEnumerator];
NSString * currentLang= nil;
while (((currentLang = [langEnumer nextObject])) && path==nil)
{
path = [self pathForResourceNamed:name
inFramework:aFrameworkName
language:currentLang];
}
}
if (path==nil)
{
// no languages or path not found
path = [self pathForResourceNamed:name
inFramework:aFrameworkName
language:nil];
}
if (path!=nil)
{
path = [self _cleanPath:path
frameworkName:aFrameworkName];
url = [NSString stringWithFormat:@"%@%@%@", [request _applicationURLPrefix],
[[GSWApp class] resourceRequestHandlerKey],
path];
}
}
return url;
}
static NSDictionary * _cachedStringsTable(GSWResourceManager * resmanager, NSString * tableName, NSString * framework, NSString * lang)
{
NSDictionary * stringTableDict = nil;
if (tableName)
{
NSString * languageKey = (!lang) ? NONESTR : lang;
NSString * frameworkNameKey = (!framework) ? NONESTR : framework;
NSString * tableKey = [NSString stringWithFormat:@"%@_%@_%@", tableName, frameworkNameKey, languageKey];
SYNCHRONIZED(TheStringsTableLock) {
stringTableDict = [TheStringsTableDictionary objectForKey:tableKey];
} END_SYNCHRONIZED;
if (!stringTableDict)
{
// load from file
if (tableName)
{
NSString * path;
path = [resmanager pathForResourceNamed:[tableName stringByAppendingString:@".strings"]
inFramework:framework
language:lang];
if (path) {
NSString * fileString = nil;
NSStringEncoding encoding = 0;
NSError * error = nil;
fileString = [NSString stringWithContentsOfFile:path
usedEncoding:&encoding
error:&error];
if (error) {
NSLog(@"%s: %@", __PRETTY_FUNCTION__, error);
} else {
stringTableDict = [fileString propertyListFromStringsFileFormat];
}
}
}
if (!stringTableDict)
{
stringTableDict = (NSDictionary*) [NSNull null];
}
SYNCHRONIZED(TheStringsTableLock) {
[TheStringsTableDictionary setObject:stringTableDict
forKey:tableKey];
} END_SYNCHRONIZED;
}
// we are using a static object so the == is ok here.
if (stringTableDict == (NSDictionary*) [NSNull null])
{
stringTableDict = nil;
}
}
return stringTableDict;
}
static NSString * _cachedStringForKey(GSWResourceManager * resmanager, NSString * key, NSString * tableName, NSString * framework, NSString * lang)
{
NSDictionary * stringTableDict = _cachedStringsTable(resmanager, tableName, framework, lang);
NSString * string = nil;
if ((stringTableDict) && (key))
{
string = [stringTableDict objectForKey:key];
}
return string;
}
/*
* Return value: string from tableName using key to look it up.
* first searches the tableName.strings file in the locale
* subdirectories. languages specifies the search order.
*/
-(NSString*)stringForKey:(NSString*)key
inTableNamed:(NSString*)aTableName
withDefaultValue:(NSString*)defaultValue
inFramework:(NSString*)framework
languages:(NSArray*)languages
{
NSString * string=nil;
NSString * tableName;
if (!aTableName) {
tableName = @"Localizable";
} else {
tableName = aTableName;
}
if (languages)
{
NSUInteger count = [languages count];
NSUInteger idx;
for(idx = 0; idx < count; idx++)
{
NSString * lang = [languages objectAtIndex:idx];
string = _cachedStringForKey(self, key, tableName, framework, lang);
if (string)
{
return string;
}
}
}
string = _cachedStringForKey(self, key, tableName, framework, nil);
if (!string)
string=defaultValue;
return string;
}
//--------------------------------------------------------------------
-(void)unlock
{
LoggedUnlock(_selfLock);
#ifndef NDEBUG
_selfLockn--;
#endif
};
//--------------------------------------------------------------------
-(void)lock
{
LoggedLockBeforeDate(_selfLock,GSW_LOCK_LIMIT);
#ifndef NDEBUG
_selfLockn++;
#endif
};
-(void)flushDataCache
{
SYNCHRONIZED(self)
{
[_urlValuedElementsData removeAllObjects];
}
END_SYNCHRONIZED;
}
-(void)_lockedCacheData:(GSWURLValuedElementData*)aData
{
NSData* data=nil;
NSString* key=nil;
data=[aData data];
NSAssert(data,@"Data");
key=[aData key];
NSAssert(key,@"No key");
if (!_urlValuedElementsData)
_urlValuedElementsData=[NSMutableDictionary new];
[_urlValuedElementsData setObject:aData
forKey:key];
}
//--------------------------------------------------------------------
-(void)setData:(NSData*)aData
forKey:(NSString*)aKey
mimeType:(NSString*)aType
session:(GSWSession*)session_ //unused
{
GSWURLValuedElementData* dataValue=nil;
dataValue=[[[GSWURLValuedElementData alloc] initWithData:aData
mimeType:aType
key:aKey] autorelease];
if ((dataValue) && ([dataValue data]))
{
SYNCHRONIZED(self)
{
[self _lockedCacheData:dataValue];
}
END_SYNCHRONIZED;
}
}
//--------------------------------------------------------------------
-(void)removeDataForKey:(NSString*)aKey
session:(GSWSession*)session //unused
{
SYNCHRONIZED(self)
{
[_urlValuedElementsData removeObjectForKey:aKey];
}
END_SYNCHRONIZED;
}
/*
must be used locked.
returns localNotFoundMarker on negative cache result.
*/
-(NSString*)_cachedPathForResourceNamed:(NSString*)resourceName
inFramework:(NSString*)frameworkName
language:(NSString*)language
{
NSString * cachedPath = nil;
NSString * key = [NSString stringWithFormat:@"%@:%@:%@",
resourceName,
(frameworkName) ? frameworkName : @"APP",
(language) ? language : NONESTR];
cachedPath = [globalPathCache objectForKey:key];
return cachedPath;
}
/*
must be used locked.
saves localNotFoundMarker into cache if path is nil.
*/
-(void)_cachePath:(NSString*)path
forResourceNamed:(NSString*)resourceName
inFramework:(NSString*)frameworkName
language:(NSString*)language
{
NSString * key = [NSString stringWithFormat:@"%@:%@:%@",
resourceName,
(frameworkName) ? frameworkName : @"APP",
(language) ? language : NONESTR];
if (!path) {
path = localNotFoundMarker;
}
[globalPathCache setObject:path
forKey:key];
}
/*
Returns the absolute path for the resource resourceName.
resourceName must include the extension.
If the file is in the application, specify nil for the frameworkName argument.
*/
-(NSString*)pathForResourceNamed:(NSString*)resourceName
inFramework:(NSString*)frameworkName
language:(NSString*)language
{
NSBundle * bundleToUse = nil;
NSString * path = nil;
SYNCHRONIZED(self)
{
path = [self _cachedPathForResourceNamed:resourceName
inFramework:frameworkName
language:language];
if (!path) {
if (!frameworkName)
{
bundleToUse = [NSBundle mainBundle];
} else {
NSEnumerator * bundleEnumer = [[NSBundle allFrameworks] objectEnumerator];
NSBundle * currentBundle;
while (((currentBundle = [bundleEnumer nextObject])) && (!bundleToUse))
{
if (([[[currentBundle infoDictionary] objectForKey:@"CFBundleExecutable"]
isEqualToString:frameworkName]) ||
([[[currentBundle infoDictionary] objectForKey:@"NSExecutable"]
isEqualToString:frameworkName]))
{
bundleToUse = currentBundle;
}
}
}
if (!bundleToUse) {
// NSLog(@"%s: could not find bundle for resource '%@' inFramework '%@'",
// __PRETTY_FUNCTION__, resourceName, frameworkName);
} else {
NSString * nameWithoutExtension = [resourceName stringByDeletingPathExtension];
NSString * pathExtension = [resourceName pathExtension];
path = [bundleToUse pathForResource:nameWithoutExtension
ofType:pathExtension
inDirectory:nil
forLocalization:language];
if (!path) {
path = [bundleToUse pathForResource:nameWithoutExtension
ofType:pathExtension
inDirectory:@"WebServer"
forLocalization:language];
}
[self _cachePath:path
forResourceNamed:resourceName
inFramework:frameworkName
language:language];
}
}
}
END_SYNCHRONIZED;
/*
NSLog(@"%s resourceName:'%@' language:'%@' frameworkName:'%@' path '%@'", __PRETTY_FUNCTION__,
resourceName, language, frameworkName,
path);
*/
if ([localNotFoundMarker isEqualToString:path])
path=nil;
return path;
}
/*
must be used locked.
returns localNotFoundMarker on negative cache result.
*/
-(NSString*)_cachedURLForResourceNamed:(NSString*)resourceName
inFramework:(NSString*)frameworkName
language:(NSString*)language
{
NSString * cachedURL = nil;
NSString * key = [NSString stringWithFormat:@"%@:%@:%@",
resourceName,
(frameworkName) ? frameworkName : @"APP",
(language) ? language : NONESTR];
cachedURL = [globalURLCache objectForKey:key];
return cachedURL;
}
/*
must be used locked.
saves localNotFoundMarker into cache if url is nil.
*/
-(void)_cacheURL:(NSString*)url
forResourceNamed:(NSString*)resourceName
inFramework:(NSString*)frameworkName
language:(NSString*)language
{
NSString * key = [NSString stringWithFormat:@"%@:%@:%@",
resourceName,
(frameworkName) ? frameworkName : @"APP",
(language) ? language : NONESTR];
if (!url)
url = localNotFoundMarker;
[globalPathCache setObject:url
forKey:key];
}
/*
Returns the url for the resource resourceName.
resourceName must include the extension.
If the file is in the application, specify nil for the frameworkName argument.
*/
-(NSString*)urlForResourceNamed:(NSString*)resourceName
inFramework:(NSString*)frameworkName
language:(NSString*)language
{
NSString * url = nil;
SYNCHRONIZED(self)
{
url = [self _cachedURLForResourceNamed:resourceName
inFramework:frameworkName
language:language];
if (url==nil)
{
NSBundle * bundleToUse = nil;
NSString* path = nil;
BOOL isApp=NO;
if (!frameworkName)
{
bundleToUse = [NSBundle mainBundle];
isApp=YES;
}
else
{
NSEnumerator * bundleEnumer = [[NSBundle allFrameworks] objectEnumerator];
NSBundle * currentBundle= nil;
while (((currentBundle = [bundleEnumer nextObject])) && bundleToUse==nil)
{
if (([[[currentBundle infoDictionary] objectForKey:@"CFBundleExecutable"]
isEqualToString:frameworkName]) ||
([[[currentBundle infoDictionary] objectForKey:@"NSExecutable"]
isEqualToString:frameworkName]))
{
bundleToUse = currentBundle;
}
}
}
if (!bundleToUse)
{
// NSLog(@"%s: could not find bundle for resource '%@' inFramework '%@'",
// __PRETTY_FUNCTION__, resourceName, frameworkName);
}
else
{
NSString * nameWithoutExtension = [resourceName stringByDeletingPathExtension];
NSString * pathExtension = [resourceName pathExtension];
path = [bundleToUse pathForResource:nameWithoutExtension
ofType:pathExtension
inDirectory:nil
forLocalization:language];
if (!path)
{
path = [bundleToUse pathForResource:nameWithoutExtension
ofType:pathExtension
inDirectory:@"WebServer"
forLocalization:language];
}
if (path!=nil)
{
NSString* baseURL=(isApp ? [[GSWApp class]applicationBaseURL] : [[GSWApp class]frameworksBaseURL]);
NSString* bundlePath = [bundleToUse bundlePath];
NSRange r=[path rangeOfString:bundlePath];
NSAssert2(r.location==0 && r.length>0,@"Path mismatch: bundlePath '%@' for '%@'.",bundlePath,path);
path=[path substringFromIndex:r.location+r.length];
url=[NSString stringWithFormat:@"%@/%@%@",
baseURL,
[bundlePath lastPathComponent],
path];
}
[self _cacheURL:url
forResourceNamed:resourceName
inFramework:frameworkName
language:language];
}
}
}
END_SYNCHRONIZED;
if ([localNotFoundMarker isEqualToString:url])
url=nil;
return url;
}
//--------------------------------------------------------------------
-(GSWDeployedBundle*)_appProjectBundle
{
return globalAppProjectBundle;
};
-(BOOL)_doesRequireJavaVirualMachine
{
[self notImplemented: _cmd]; //TODOFN
return NO;
};
//--------------------------------------------------------------------
-(NSString *) _absolutePathForJavaClassPath:(NSString*)path
{
[self notImplemented: _cmd]; //TODOFN
return nil;
}
//--------------------------------------------------------------------
// used by GSWResourceRequestHandler
-(GSWURLValuedElementData*)_cachedDataForKey:(NSString*)key
{
//OK
GSWURLValuedElementData* data=nil;
[self lock];
NS_DURING
{
data=[_urlValuedElementsData objectForKey:key];
}
NS_HANDLER
{
//TODO
[self unlock];
[localException raise];
}
NS_ENDHANDLER;
[self unlock];
return data;
};
//--------------------------------------------------------------------
// TODO: find out what the real name for this is.
//- (NSString*) contentTypeForResourceNamed:(NSString*) aName
-(NSString*)contentTypeForResourcePath:(NSString*)path
{
//OK
NSString* type=nil;
NSString* extension=nil;
extension=[path pathExtension];
if (extension)
{
extension=[extension lowercaseString];
type=[globalMime objectForKey:extension];
};
if (!type)
type=@"application/octet-stream";
return type;
};
//--------------------------------------------------------------------
// TODO: Check if we really need this
-(NSArray*)_frameworkClassPaths
{
return _frameworkClassPaths;
};
//--------------------------------------------------------------------
/* Deprecated in WO 4.0.
* Use urlForResourceNamed:inFramework:languages:request: instead.
*/
-(NSString*)urlForResourceNamed:(NSString*)resourceName
inFramework:(NSString*)aFrameworkName
{
NSString* url=nil;
url=[self urlForResourceNamed:resourceName
inFramework:aFrameworkName
languages:nil
request:nil];
return url;
}
//--------------------------------------------------------------------
/* Deprecated in WO 4.0.
* Use pathForResourceNamed:inFramework:languages: instead.
*/
-(NSString*)pathForResourceNamed:(NSString*)resourceName
inFramework:(NSString*)aFrameworkName
{
NSString* path=nil;
path=[self pathForResourceNamed:resourceName
inFramework:aFrameworkName
language:nil];
return path;
}
//--------------------------------------------------------------------
/*
* more specific names like 'ja-jp' have priority over 'ja'
* that way, de-at could return a different language than 'de'
* As they have some different words...
*/
+(NSString*)GSLanguageFromISOLanguage:(NSString*)ISOLanguage
{
NSString * searchStr = [[ISOLanguage stringByTrimmingSpaces] lowercaseString];
NSString * langName = nil;
langName = [localISO2GSLanguages objectForKey:searchStr];
if (!langName) {
// try to get only the prefix of 'ja-jp'
NSRange minusRange = [searchStr rangeOfString:@"-"];
if (minusRange.location != NSNotFound) {
searchStr = [searchStr substringToIndex:minusRange.location];
langName = [localISO2GSLanguages objectForKey:searchStr];
}
}
return langName;
}
//--------------------------------------------------------------------
//NDFN
+(NSArray*)GSLanguagesFromISOLanguages:(NSArray*)ISOLanguages
{
NSArray* GSLanguages=nil;
if (ISOLanguages)
{
NSMutableArray* array=[NSMutableArray array];
NSString* ISOLanguage=nil;
NSString* GSLanguage=nil;
int i=0;
int ISOLanguagesCount=[ISOLanguages count];
for(i=0;i<ISOLanguagesCount;i++)
{
ISOLanguage=[ISOLanguages objectAtIndex:i];
GSLanguage=[self GSLanguageFromISOLanguage:ISOLanguage];
if (GSLanguage)
[array addObject:GSLanguage];
else
{
NSLog(@"Unknown language: %@\nKnown languages are : %@",ISOLanguage,localISO2GSLanguages);
};
};
GSLanguages=[NSArray arrayWithArray:array];
}
return GSLanguages;
};
//--------------------------------------------------------------------
//NDFN
+(NSString*)ISOLanguageFromGSLanguage:(NSString*)GSLanguage
{
return [localGS2ISOLanguages objectForKey:[[GSLanguage stringByTrimmingSpaces] lowercaseString]];
};
//--------------------------------------------------------------------
//NDFN
+(NSArray*)ISOLanguagesFromGSLanguages:(NSArray*)GSLanguages
{
NSArray* ISOLanguages=nil;
if (GSLanguages)
{
NSMutableArray* array=[NSMutableArray array];
NSString* ISOLanguage=nil;
NSString* GSLanguage=nil;
int i=0;
int GSLanguagesCount=[GSLanguages count];
for(i=0;i<GSLanguagesCount;i++)
{
GSLanguage=[GSLanguages objectAtIndex:i];
ISOLanguage=[self ISOLanguageFromGSLanguage:GSLanguage];
NSDebugMLog(@"ISOLanguage=%@",ISOLanguage);
if (ISOLanguage)
[array addObject:ISOLanguage];
else
{
NSLog(@"Unknown language: %@\nKnown languages are : %@",GSLanguage,localGS2ISOLanguages);
};
};
ISOLanguages=[NSArray arrayWithArray:array];
}
return ISOLanguages;
};
// wo
- (NSString *) errorMessageUrlForResourceNamed:(NSString *) resourceName
inFramework:(NSString *) frameworkName
{
NSString * url = nil;
if( resourceName == nil)
{
resourceName = @"nil";
}
if (frameworkName != nil)
{
url = [NSString stringWithFormat:@"/ERROR/NOT_FOUND/framework=%@/filename=%@", frameworkName, resourceName];
}
else
{
NSString * s3 = [GSWApp name];
url = [NSString stringWithFormat:@"/ERROR/NOT_FOUND/app=%@/filename=%@", s3, resourceName];
}
return url;
}
// checkme: locking?? davew
- (void) _cacheData:(GSWURLValuedElementData *) aData
{
if (aData != nil)
{
[_urlValuedElementsData setObject: aData
forKey: [aData key]];
}
}
- (GSWImageInfo *) _imageInfoForUrl:(NSString *)resourceURL
fileName:(NSString *)filename
framework:(NSString *)frameworkName
languages:(NSArray *)languages
{
NSString *path = nil;
path = [self pathForResourceNamed:filename
inFramework:frameworkName
languages:languages];
return [GSWImageInfo imageInfoWithFile: path];
}
@end