/** GSWBundle.m - GSWeb: Class GSWBundle Copyright (C) 1999-2002 Free Software Foundation, Inc. Written by: Manuel Guesdon Date: Mar 1999 $Revision$ $Date$ This file is part of the GNUstep Web Library. 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. **/ static char rcsId[] = "$Id$"; #include #ifdef GDL2 //==================================================================== @interface GSWBundleUnarchiverDelegate : NSObject { id _object; } - (id) unarchiver:(EOKeyValueUnarchiver*)unarchiver objectForReference:(NSString*)keyPath; - (id) initWithObject:(id)object; @end //==================================================================== @implementation GSWBundleUnarchiverDelegate //-------------------------------------------------------------------- - (void) dealloc { [super dealloc]; }; //-------------------------------------------------------------------- - (id) unarchiver:(EOKeyValueUnarchiver*)unarchiver objectForReference:(NSString*)keyPath { return [_object valueForKeyPath:keyPath]; }; //-------------------------------------------------------------------- - (id) initWithObject:(id)object { if ((self=[super init])) { _object=object; }; return self; }; @end #endif // GDL2 //==================================================================== @implementation GSWBundle //-------------------------------------------------------------------- -(id)initWithPath:(NSString*)aPath baseURL:(NSString*)aBaseURL { return [self initWithPath:aPath baseURL:aBaseURL inFrameworkNamed:nil]; }; //-------------------------------------------------------------------- -(id)initWithPath:(NSString*)aPath baseURL:(NSString*)aBaseURL inFrameworkNamed:(NSString*)aFrameworkName { if ((self=[super init])) { LOGObjectFnStart(); NSDebugMLLog(@"bundles",@"aPath=%@",aPath); NSDebugMLLog(@"bundles",@"aBaseURL=%@",aBaseURL); ASSIGN(_path,[aPath stringGoodPath]); NSDebugMLLog(@"bundles",@"path=%@",_path); ASSIGN(_baseURL,aBaseURL); ASSIGN(_frameworkName,aFrameworkName); _archiveCache=[NSMutableDictionary new]; _apiCache=[NSMutableDictionary new]; _encodingCache=[NSMutableDictionary new]; _templateParserTypeCache=[NSMutableDictionary new]; _pathCache=[NSMutableDictionary new]; _urlCache=[NSMutableDictionary new]; _stringsTableCache=[NSMutableDictionary new]; _stringsTableArrayCache=[NSMutableDictionary new]; _templateCache=[NSMutableDictionary new]; _classCache=[NSMutableDictionary new]; _selfLock=[NSRecursiveLock new]; LOGObjectFnStop(); }; return self; }; //-------------------------------------------------------------------- -(void)dealloc { GSWLogC("Dealloc GSWBundle"); GSWLogC("Dealloc GSWBundle: path"); DESTROY(_path); GSWLogC("Dealloc GSWBundle: baseURL"); DESTROY(_baseURL); GSWLogC("Dealloc GSWBundle: archiveCache"); DESTROY(_archiveCache); GSWLogC("Dealloc GSWBundle: apiCache"); DESTROY(_apiCache); GSWLogC("Dealloc GSWBundle: encodingCache"); DESTROY(_encodingCache); GSWLogC("Dealloc GSWBundle: templateParserTypeCache"); DESTROY(_templateParserTypeCache); GSWLogC("Dealloc GSWBundle: pathCache"); DESTROY(_pathCache); GSWLogC("Dealloc GSWBundle: urlCache"); DESTROY(_urlCache); GSWLogC("Dealloc GSWBundle: stringsTableCache"); DESTROY(_stringsTableCache); GSWLogC("Dealloc GSWBundle: stringsTableArrayCache"); DESTROY(_stringsTableArrayCache); GSWLogC("Dealloc GSWBundle: templateCache"); DESTROY(_templateCache); GSWLogC("Dealloc GSWBundle: classCache"); DESTROY(_classCache); GSWLogC("Dealloc GSWBundle: selfLock"); DESTROY(_selfLock); GSWLogC("Dealloc GSWBundle Super"); [super dealloc]; GSWLogC("End Dealloc GSWBundle"); }; //-------------------------------------------------------------------- -(NSString*)baseURL { return _baseURL; }; //-------------------------------------------------------------------- -(NSString*)path { return _path; }; //-------------------------------------------------------------------- -(NSString*)frameworkName { return _frameworkName; }; //-------------------------------------------------------------------- -(NSString*)description { NSString* descr=nil; // GSWLogC("GSWBundle description A"); // NSDebugMLLog(@"bundles",@"GSWBundle description Self=%p",self); descr=[NSString stringWithFormat:@"<%s %p - ", object_get_class_name(self), (void*)self]; // GSWLogC("GSWBundle description B"); descr=[descr stringByAppendingFormat:@"path:[%@] ", _path]; // GSWLogC("GSWBundle description C"); descr=[descr stringByAppendingFormat:@"baseURL:[%@] frameworkName:[%@]>", _baseURL, _frameworkName]; // GSWLogC("GSWBundle description D"); return descr; }; //-------------------------------------------------------------------- -(void)unlock { LOGObjectFnStart(); NSDebugMLLog(@"bundles",@"selfLockn=%d",_selfLockn); TmpUnlock(_selfLock); #ifndef NDEBUG _selfLockn--; #endif NSDebugMLLog(@"bundles",@"selfLockn=%d",_selfLockn); LOGObjectFnStop(); }; //-------------------------------------------------------------------- -(void)lock { LOGObjectFnStart(); NSDebugMLLog(@"bundles",@"selfLockn=%d",_selfLockn); TmpLockBeforeDate(_selfLock,[NSDate dateWithTimeIntervalSinceNow:GSLOCK_DELAY_S]); #ifndef NDEBUG _selfLockn++; #endif NSDebugMLLog(@"bundles",@"selfLockn=%d",_selfLockn); LOGObjectFnStop(); }; @end //==================================================================== @implementation GSWBundle (GSWBundleCache) //-------------------------------------------------------------------- -(void)clearCache { //OK LOGObjectFnStart(); [self lock]; NS_DURING { //TemplateCache clearr ? LOGObjectFnNotImplemented(); //TODOFN } NS_HANDLER { NSDebugMLLog(@"bundles",@"EXCEPTION:%@ (%@) [%s %d]", localException,[localException reason],__FILE__,__LINE__); //TODO [self unlock]; [localException raise]; }; NS_ENDHANDLER; [self unlock]; LOGObjectFnStop(); }; //-------------------------------------------------------------------- -(void)loadCache { LOGObjectFnNotImplemented(); //TODOFN }; @end //==================================================================== @implementation GSWBundle (GSWBundleA) -(id)lockedResourceNamed:(NSString*)aName ofType:(NSString*)aType withLanguages:(NSArray*)someLanguages usingCache:(NSMutableDictionary*)aCache relativePath:(NSString**)aRelativePath absolutePath:(NSString**)anAbsolutePath { int languageIndex=0; NSString* relativePath=nil; NSString* absolutePath=nil; NSString* fileName=nil; NSString* language=nil; id resource=nil; NSString* path=nil; NSFileManager* fileManager=nil; int languagesNb=nil; BOOL exists=NO; LOGObjectFnStart(); NSDebugMLLog(@"bundles",@"type=%@",aType); languagesNb=[someLanguages count]; fileManager=[NSFileManager defaultManager]; NSAssert(fileManager,@"No fileManager"); fileName=[NSString stringWithFormat:@"%@.%@",aName,aType]; NSDebugMLLog(@"bundles",@"fileName=%@",fileName); for(languageIndex=0;!resource && !path && languageIndex<=languagesNb;languageIndex++) { language=nil; if (languageIndex==languagesNb) relativePath=[NSString stringWithFormat:@"/%@", fileName]; else { language=[someLanguages objectAtIndex:languageIndex]; relativePath=[NSString stringWithFormat:@"/%@.%@/%@", language, GSLanguageSuffix, fileName]; }; NSDebugMLLog(@"bundles",@"language=%@",language); NSDebugMLLog(@"bundles",@"relativePath=%@",relativePath); absolutePath=[_path stringByAppendingString:relativePath]; NSDebugMLLog(@"bundles",@"absolutePath=%@",absolutePath); if ([[GSWApplication application] isCachingEnabled]) resource=[aCache objectForKey:relativePath]; NSDebugMLLog(@"bundles",@"resource=%@",resource); if (resource==GSNotFoundMarker) { resource=nil; absolutePath=nil; relativePath=nil; } else if (!resource) { exists=[fileManager fileExistsAtPath:absolutePath]; NSDebugMLLog(@"bundles",@"%@ exists=%s",absolutePath,(exists ? "YES" : "NO")); if (!exists) { if ([[GSWApplication application] isCachingEnabled]) [aCache setObject:GSNotFoundMarker forKey:relativePath]; relativePath=nil; absolutePath=nil; }; }; }; if (aRelativePath) *aRelativePath=relativePath; if (anAbsolutePath) *anAbsolutePath=absolutePath; LOGObjectFnStop(); return resource; }; @end //==================================================================== @implementation GSWBundle (GSWResourceManagement) //-------------------------------------------------------------------- -(void)initializeObject:(id)anObject fromArchiveNamed:(NSString*)aName { //OK NSDictionary* archive=nil; LOGObjectFnStart(); NSDebugMLLog(@"bundles",@"anObject:%@",anObject); NSDebugMLLog(@"bundles",@"aName:%@",aName); //call application _isDynamicLoadingEnabled //call -- isTerminating //call -- isCachingEnabled //call -- isPageRefreshOnBacktrackEnabled//0 archive=[self archiveNamed:aName]; //Verify NSDebugMLLog(@"bundles",@"archive:%@",archive); if (archive) [self initializeObject:anObject fromArchive:archive]; LOGObjectFnStop(); }; //-------------------------------------------------------------------- -(void)initializeObject:(id)anObject fromArchive:(NSDictionary*)anArchive { LOGObjectFnStart(); NSDebugMLLog(@"bundles",@"anObject:%@",anObject); NSDebugMLLog(@"bundles",@"anArchive:%@",anArchive); [self lock]; NS_DURING { if (!WOStrictFlag) { NSDictionary* userDictionary=[anArchive objectForKey:@"userDictionary"]; NSDictionary* userAssociations=[anArchive objectForKey:@"userAssociations"]; NSDictionary* defaultAssociations=[anArchive objectForKey:@"defaultAssociations"]; NSDebugMLLog(@"bundles",@"userDictionary:%@",userDictionary); NSDebugMLLog(@"bundles",@"userAssociations:%@",userAssociations); NSDebugMLLog(@"bundles",@"defaultAssociations:%@",defaultAssociations); userAssociations=[userAssociations dictionaryByReplacingStringsWithAssociations]; NSDebugMLLog(@"bundles",@"userAssociations:%@",userAssociations); defaultAssociations=[defaultAssociations dictionaryByReplacingStringsWithAssociations]; NSDebugMLLog(@"bundles",@"defaultAssociations:%@",defaultAssociations); if (userDictionary && [anObject respondsToSelector:@selector(setUserDictionary:)]) [anObject setUserDictionary:userDictionary]; if (userAssociations && [anObject respondsToSelector:@selector(setUserAssociations:)]) [anObject setUserAssociations:userAssociations]; if (defaultAssociations && [anObject respondsToSelector:@selector(setDefaultAssociations:)]) [anObject setDefaultAssociations:defaultAssociations]; }; #if GDL2 // GDL2 implementation { EOKeyValueUnarchiver* unarchiver=nil; GSWBundleUnarchiverDelegate* bundleDelegate=nil; NSDictionary* variables=nil; NSEnumerator* variablesEnum=nil; id variableName=nil; NSDebugMLLog(@"bundles",@"anArchive %p:%@",anArchive,anArchive); unarchiver=[[[EOKeyValueUnarchiver alloc] initWithDictionary:anArchive] autorelease]; NSDebugMLLog(@"bundles",@"unarchiver %p:%@",unarchiver,unarchiver); bundleDelegate=[[[GSWBundleUnarchiverDelegate alloc] initWithObject:anObject] autorelease]; NSDebugMLLog(@"bundles",@"bundleDelegate %p:%@",bundleDelegate,bundleDelegate); [unarchiver setDelegate:bundleDelegate]; NSDebugMLLog(@"bundles",@"decodevar here=%p",[NSString string]); variables=[unarchiver decodeObjectForKey:@"variables"]; NSDebugMLLog(@"bundles",@"variables %p:%@",variables,variables); [unarchiver finishInitializationOfObjects]; NSDebugMLLog(@"bundles",@"here=%p",[NSString string]); [unarchiver awakeObjects]; variablesEnum=[variables keyEnumerator]; NSDebugMLLog(@"bundles",@"here=%p",[NSString string]); NSDebugMLLog0(@"bundles",@"Will set variables"); while ((variableName = [variablesEnum nextObject])) { id variableValue=[variables objectForKey:variableName]; NSDebugMLLog(@"bundles",@"ObjectClas=%@ variableName %p:%@ variableValue %p:%@", [anObject class], variableName, variableName, variableValue, variableValue); NSDebugMLLog(@"bundles",@"BEF variableValue %p:%@ [RC=%d]", variableValue, variableValue, [variableValue retainCount]); [anObject smartTakeValue:variableValue forKey:variableName]; NSDebugMLLog(@"bundles",@"AFT variableValue %p:%@ [RC=%d]", variableValue, variableValue, [variableValue retainCount]); }; }; #else LOGObjectFnNotImplemented(); #endif } NS_HANDLER { NSDebugMLog(@"EXCEPTION:%@ (%@) [%s %d] anObject=%p class=%@ superClass=%@ ", localException, [localException reason], __FILE__, __LINE__, anObject, [anObject class], [anObject superclass]); //TODO [self unlock]; [localException raise]; }; NS_ENDHANDLER; [self unlock]; LOGObjectFnStop(); }; //-------------------------------------------------------------------- -(Class)scriptedClassWithName:(NSString*)aName superclassName:(NSString*)aSuperclassName { //OK Class aClass=nil; NSString* pathName=nil; LOGObjectFnStart(); NSDebugMLLog(@"bundles",@"Name=%@",aName); NSDebugMLLog(@"bundles",@"aSuperclassName=%@",aSuperclassName); [self lock]; NS_DURING { pathName=[self lockedScriptedClassPathWithName:aName]; //Verify if (pathName) { aClass=[self lockedScriptedClassWithName:aName pathName:pathName superclassName:aSuperclassName]; }; } NS_HANDLER { NSDebugMLLog(@"bundles",@"EXCEPTION:%@ (%@) [%s %d]", localException,[localException reason],__FILE__,__LINE__); //TODO [self unlock]; [localException raise]; }; NS_ENDHANDLER; [self unlock]; LOGObjectFnStop(); return aClass; }; //-------------------------------------------------------------------- -(Class)lockedScriptedClassWithName:(NSString*)aName pathName:(NSString*)aPathName superclassName:(NSString*)aSuperclassName { LOGObjectFnNotImplemented(); //TODOFN return nil; }; //-------------------------------------------------------------------- -(NSString*)lockedScriptedClassPathWithName:(NSString*)aName { NSString* path=nil; id script=nil; script=[self lockedResourceNamed:aName ofType:GSWScriptSuffix[GSWebNamingConv] withLanguages:nil usingCache:_classCache relativePath:NULL absolutePath:&path]; if (!script && !path) script=[self lockedResourceNamed:aName ofType:GSWScriptSuffix[GSWebNamingConvInversed] withLanguages:nil usingCache:_classCache relativePath:NULL absolutePath:&path]; return path; }; //-------------------------------------------------------------------- -(Class)compiledClassWithName:(NSString*)aName superclassName:(NSString*)aSuperclassName { LOGObjectFnNotImplemented(); //TODOFN return nil; }; //-------------------------------------------------------------------- -(GSWElement*)templateNamed:(NSString*)aName languages:(NSArray*)someLanguages { GSWElement* template=nil; LOGObjectFnStart(); NSDebugMLLog(@"bundles",@"Name=%@",aName); //OK [self lock]; NS_DURING { template=[self lockedTemplateNamed:aName languages:someLanguages]; } NS_HANDLER { NSDebugMLLog(@"bundles",@"EXCEPTION:%@ (%@) [%s %d]", localException,[localException reason],__FILE__,__LINE__); //TODO [self unlock]; localException=ExceptionByAddingUserInfoObjectFrameInfo0(localException, @"In lockedTemplateNamed"); [localException raise]; }; NS_ENDHANDLER; [self unlock]; NSDebugMLLog(@"bundles",@"template=%@",template); LOGObjectFnStop(); return template; }; //-------------------------------------------------------------------- -(GSWElement*)lockedTemplateNamed:(NSString*)aName languages:(NSArray*)someLanguages { //OK GSWElement* template=nil; NSString* relativeTemplatePath=nil; NSString* absoluteTemplatePath=nil; LOGObjectFnStart(); NSDebugMLLog(@"bundles",@"AName=%@",aName); NSDebugMLLog(@"bundles",@"SomeLanguages=%@",someLanguages); NSDebugMLLog(@"bundles",@"Path=%@",_path); NSDebugMLLog(@"bundles",@"baseURL=%@",_baseURL); NSDebugMLLog(@"bundles",@"frameworkName=%@",_frameworkName); template=[self lockedResourceNamed:aName ofType:GSWComponentTemplateSuffix withLanguages:someLanguages usingCache:_templateCache relativePath:&relativeTemplatePath absolutePath:&absoluteTemplatePath]; if (!template) { if (!relativeTemplatePath) { NSDebugMLLog(@"errors",@"No template named:%@ for languages:%@", aName, someLanguages); } else { GSWTemplateParserType templateParserType=[self templateParserTypeForResourcesNamed:aName]; NSStringEncoding encoding=[self encodingForResourcesNamed:aName]; NSString* pageDefString=nil; //TODO use encoding ! NSString* htmlString=[NSString stringWithContentsOfFile:absoluteTemplatePath]; NSDebugMLLog(@"bundles",@"htmlPath=%@",absoluteTemplatePath); if (!htmlString) { NSDebugMLLog(@"errors",@"No html file for template named:%@ for languages:%@", aName, someLanguages); } else { NSString* absoluteDefinitionPath=nil; pageDefString=[self lockedResourceNamed:aName ofType:GSWComponentDefinitionSuffix[GSWebNamingConv] withLanguages:someLanguages usingCache:nil relativePath:NULL absolutePath:&absoluteDefinitionPath]; NSDebugMLLog(@"bundles",@"absoluteDefinitionPath=%@", absoluteDefinitionPath); if (!pageDefString && !absoluteDefinitionPath) { pageDefString=[self lockedResourceNamed:aName ofType:GSWComponentDefinitionSuffix[GSWebNamingConvInversed] withLanguages:someLanguages usingCache:nil relativePath:NULL absolutePath:&absoluteDefinitionPath]; NSDebugMLLog(@"bundles",@"absoluteDefinitionPath=%@", absoluteDefinitionPath); }; if (absoluteDefinitionPath) { //TODO use encoding ! NSDebugMLLog(@"bundles",@"absoluteDefinitionPath=%@", absoluteDefinitionPath); pageDefString=[NSString stringWithContentsOfFile:absoluteDefinitionPath]; }; #ifndef NDEBUG NS_DURING #endif { NSDebugMLLog(@"bundles",@"GSWTemplateParser on template named %@", aName); template=[GSWTemplateParser templateNamed:aName inFrameworkNamed:[self frameworkName] withParserType:templateParserType parserClassName:nil withString:htmlString encoding:encoding fromPath:absoluteTemplatePath definitionsString:pageDefString languages:someLanguages definitionPath:absoluteDefinitionPath]; } #ifndef NDEBUG NS_HANDLER { NSDebugMLLog(@"bundles",@"EXCEPTION:%@ (%@) [%s %d]", localException, [localException reason], __FILE__, __LINE__); localException=ExceptionByAddingUserInfoObjectFrameInfo0(localException, @"In template Parsing"); [localException raise]; }; NS_ENDHANDLER; #endif GSWLogC("TemplateParsed\n"); NSDebugMLLog(@"bundles",@"template=%@",template); }; if ([[GSWApplication application] isCachingEnabled]) { if (template) [_templateCache setObject:template forKey:relativeTemplatePath]; else [_templateCache setObject:GSNotFoundMarker forKey:relativeTemplatePath]; }; }; }; NSDebugMLLog(@"bundles",@"template=%@",template); LOGObjectFnStop(); return template; }; //-------------------------------------------------------------------- -(NSString*)stringForKey:(NSString*)aKey inTableNamed:(NSString*)aName withDefaultValue:(NSString*)defaultValue languages:(NSArray*)someLanguages { NSDictionary* stringsTable=nil; NSString* string=nil; LOGObjectFnStart(); NSDebugMLLog(@"bundles",@"AKey=%@",aKey); NSDebugMLLog(@"bundles",@"aName=%@",aName); NSDebugMLLog(@"bundles",@"SomeLanguages=%@",someLanguages); NSDebugMLLog(@"bundles",@"defaultValue_=%@",defaultValue); stringsTable=[self stringsTableNamed:aName withLanguages:someLanguages]; if (stringsTable) string=[stringsTable objectForKey:aKey]; if (!string) string=defaultValue; LOGObjectFnStop(); return string; }; //-------------------------------------------------------------------- //NDFN -(NSDictionary*)stringsTableNamed:(NSString*)aName withLanguages:(NSArray*)someLanguages { NSDictionary* stringsTable=nil; LOGObjectFnStart(); NSDebugMLLog(@"bundles",@"aName=%@",aName); NSDebugMLLog(@"bundles",@"SomeLanguages=%@",someLanguages); [self lock]; NS_DURING { NSString* relativePath=nil; NSString* absolutePath=nil; LOGObjectFnStart(); stringsTable=[self lockedResourceNamed:aName ofType:GSWStringTableSuffix withLanguages:someLanguages usingCache:_stringsTableCache relativePath:&relativePath absolutePath:&absolutePath]; if (!stringsTable) { if (absolutePath) { //TODO use encoding ?? stringsTable=[NSDictionary dictionaryWithContentsOfFile:absolutePath]; if (!stringsTable) { NSString* tmpString=[NSString stringWithContentsOfFile:absolutePath]; LOGSeriousError(@"Bad stringTable \n%@\n from file %@", tmpString, absolutePath); }; if ([[GSWApplication application] isCachingEnabled]) { if (stringsTable) [_stringsTableCache setObject:stringsTable forKey:relativePath]; else [_stringsTableCache setObject:GSNotFoundMarker forKey:relativePath]; }; }; }; } NS_HANDLER { NSDebugMLLog(@"bundles",@"EXCEPTION:%@ (%@) [%s %d]", localException,[localException reason],__FILE__,__LINE__); //TODO [self unlock]; [localException raise]; }; NS_ENDHANDLER; [self unlock]; LOGObjectFnStop(); return stringsTable; }; //-------------------------------------------------------------------- //NDFN -(NSArray*)stringsTableArrayNamed:(NSString*)aName withLanguages:(NSArray*)someLanguages { NSArray* stringsTableArray=nil; LOGObjectFnStart(); NSDebugMLLog(@"bundles",@"aName=%@",aName); NSDebugMLLog(@"bundles",@"SomeLanguages=%@",someLanguages); [self lock]; NS_DURING { NSString* relativePath=nil; NSString* absolutePath=nil; LOGObjectFnStart(); stringsTableArray=[self lockedResourceNamed:aName ofType:GSWStringTableArraySuffix withLanguages:someLanguages usingCache:_stringsTableArrayCache relativePath:&relativePath absolutePath:&absolutePath]; if (!stringsTableArray) { if (absolutePath) { //TODO use encoding ?? stringsTableArray=[NSArray arrayWithContentsOfFile:absolutePath]; if (!stringsTableArray) { NSString* tmpString=[NSString stringWithContentsOfFile:absolutePath]; LOGSeriousError(@"Bad stringTableArray \n%@\n from file %@", tmpString, absolutePath); }; if ([[GSWApplication application] isCachingEnabled]) { if (stringsTableArray) [_stringsTableArrayCache setObject:stringsTableArray forKey:relativePath]; else [_stringsTableArrayCache setObject:GSNotFoundMarker forKey:relativePath]; }; }; }; } NS_HANDLER { localException=ExceptionByAddingUserInfoObjectFrameInfo0(localException, @"During stringsTableArrayNamed:withLanguages:"); LOGException(@"exception=%@",localException); //TODO [self unlock]; [localException raise]; }; NS_ENDHANDLER; [self unlock]; LOGObjectFnStop(); return stringsTableArray; }; //-------------------------------------------------------------------- -(NSString*)urlForResourceNamed:(NSString*)aName ofType:(NSString*)aType languages:(NSArray*)someLanguages request:(GSWRequest*)aRequest { BOOL isUsingWebServer=NO; NSString* url=nil; LOGObjectFnStart(); isUsingWebServer=[aRequest _isUsingWebServer]; [self lock]; NS_DURING { NSString* relativePath=nil; NSString* absolutePath=nil; NSString* baseURL=nil; LOGObjectFnStart(); baseURL=[self lockedResourceNamed:aName ofType:aType withLanguages:someLanguages usingCache:_urlCache relativePath:&relativePath absolutePath:&absolutePath]; if (!baseURL) { if (relativePath) { baseURL=relativePath; if ([[GSWApplication application] isCachingEnabled]) { [_pathCache setObject:baseURL forKey:relativePath]; }; }; }; if (baseURL) { if (isUsingWebServer) { url=[_baseURL stringByAppendingString:baseURL]; } else { NSString* completePath=[_path stringByAppendingString:baseURL]; url=(NSString*)[aRequest _urlWithRequestHandlerKey:GSWResourceRequestHandlerKey[GSWebNamingConv] path:nil queryString:[NSString stringWithFormat:@"%@=%@", GSWKey_Data[GSWebNamingConv], completePath]];//TODO Escape }; }; } NS_HANDLER { NSDebugMLLog(@"bundles",@"EXCEPTION:%@ (%@) [%s %d]", localException,[localException reason],__FILE__,__LINE__); //TODO [self unlock]; [localException raise]; }; NS_ENDHANDLER; [self unlock]; LOGObjectFnStop(); return url; }; //-------------------------------------------------------------------- -(NSString*)pathForResourceNamed:(NSString*)aName ofType:(NSString*)aType languages:(NSArray*)someLanguages { NSString* absolutePath=nil; LOGObjectFnStart(); NSDebugMLLog(@"bundles",@"aName=%@",aName); NSDebugMLLog(@"bundles",@"aType=%@",aType); NSDebugMLLog(@"bundles",@"someLanguages=%@",someLanguages); [self lock]; NS_DURING { NSString* path=nil; NSString* relativePath=nil; LOGObjectFnStart(); path=[self lockedResourceNamed:aName ofType:aType withLanguages:someLanguages usingCache:_stringsTableCache relativePath:&relativePath absolutePath:&absolutePath]; if (path) absolutePath=path; else if (absolutePath &&[[GSWApplication application] isCachingEnabled]) { [_pathCache setObject:absolutePath forKey:relativePath]; }; } NS_HANDLER { NSDebugMLLog(@"bundles",@"EXCEPTION:%@ (%@) [%s %d]", localException,[localException reason],__FILE__,__LINE__); //TODO [self unlock]; [localException raise]; }; NS_ENDHANDLER; [self unlock]; LOGObjectFnStop(); return absolutePath; }; //-------------------------------------------------------------------- -(NSStringEncoding)encodingForResourcesNamed:(NSString*)aName { NSDictionary* archive=nil; NSStringEncoding encoding=GSUndefinedEncoding; id encodingObject=nil; LOGObjectFnStart(); [self lock]; NS_DURING { NSDebugMLLog(@"bundles",@"aName=%@",aName); NSDebugMLLog(@"bundles",@"encodingCache=%@",_encodingCache); NSDebugMLLog(@"bundles",@"archiveCache=%@",_archiveCache); encodingObject=[_encodingCache objectForKey:aName]; if (!encodingObject) { archive=[self archiveNamed:aName]; if (archive) { encodingObject=[archive objectForKey:@"encoding"]; if (encodingObject) { encodingObject=[NSNumber valueFromString:encodingObject]; [_encodingCache setObject:encodingObject forKey:aName]; }; }; }; if (encodingObject) encoding=[encodingObject unsignedIntValue]; } NS_HANDLER { NSDebugMLLog(@"bundles",@"EXCEPTION:%@ (%@) [%s %d]", localException,[localException reason],__FILE__,__LINE__); //TODO [self unlock]; [localException raise]; }; NS_ENDHANDLER; [self unlock]; LOGObjectFnStop(); return encoding; }; //-------------------------------------------------------------------- -(GSWTemplateParserType)templateParserTypeForResourcesNamed:(NSString*)aName { NSDictionary* archive=nil; GSWTemplateParserType templateParserType=GSWTemplateParserType_Default; id templateParserTypeObject=nil; LOGObjectFnStart(); [self lock]; NS_DURING { NSDebugMLLog(@"bundles",@"aName=%@",aName); NSDebugMLLog(@"bundles",@"templateParserTypeCache=%@",_templateParserTypeCache); NSDebugMLLog(@"bundles",@"archiveCache=%@",_archiveCache); templateParserTypeObject=[_templateParserTypeCache objectForKey:aName]; if (!templateParserTypeObject) { archive=[self archiveNamed:aName]; if (archive) { templateParserTypeObject=[archive objectForKey:@"templateParserType"]; if (templateParserTypeObject) { templateParserTypeObject=[NSNumber valueWithInt:[GSWTemplateParser templateParserTypeFromString:templateParserTypeObject]]; [_templateParserTypeCache setObject:templateParserTypeObject forKey:aName]; }; }; }; if (templateParserTypeObject) templateParserType=[templateParserTypeObject intValue]; } NS_HANDLER { NSDebugMLLog(@"bundles",@"EXCEPTION:%@ (%@) [%s %d]", localException,[localException reason],__FILE__,__LINE__); //TODO [self unlock]; [localException raise]; }; NS_ENDHANDLER; [self unlock]; LOGObjectFnStop(); return templateParserType; }; //-------------------------------------------------------------------- -(NSDictionary*)archiveNamed:(NSString*)aName { //OK NSDictionary* archive=nil; LOGObjectFnStart(); NSDebugMLLog(@"bundles",@"aName=%@",aName); [self lock]; NS_DURING { archive=[self lockedArchiveNamed:aName]; NSDebugMLLog(@"bundles",@"archive=%@",archive); } NS_HANDLER { NSDebugMLLog(@"bundles",@"EXCEPTION:%@ (%@) [%s %d]", localException,[localException reason],__FILE__,__LINE__); //TODO [self unlock]; [localException raise]; }; NS_ENDHANDLER; [self unlock]; NSDebugMLLog(@"bundles",@"archive=%@",archive); LOGObjectFnStop(); return archive; }; //-------------------------------------------------------------------- -(NSDictionary*)lockedArchiveNamed:(NSString*)aName { //OK NSDictionary* archive=nil; NSString* relativePath=nil; NSString* absolutePath=nil; BOOL isCachingEnabled=NO; LOGObjectFnStart(); NSDebugMLLog(@"bundles",@"search=%@.%@",aName,GSWArchiveSuffix[GSWebNamingConv]); archive=[self lockedResourceNamed:aName ofType:GSWArchiveSuffix[GSWebNamingConv] withLanguages:nil usingCache:_archiveCache relativePath:&relativePath absolutePath:&absolutePath]; NSDebugMLLog(@"bundles",@"archive=%p absolutePath=%@",archive,absolutePath); if (!archive && !absolutePath) { NSDebugMLLog(@"bundles",@"search=%@.%@",aName,GSWArchiveSuffix[GSWebNamingConvInversed]); archive=[self lockedResourceNamed:aName ofType:GSWArchiveSuffix[GSWebNamingConvInversed] withLanguages:nil usingCache:_archiveCache relativePath:&relativePath absolutePath:&absolutePath]; NSDebugMLLog(@"bundles",@"archive=%p absolutePath=%@",archive,absolutePath); }; if (!archive) { if (absolutePath) { archive=[NSDictionary dictionaryWithContentsOfFile:absolutePath]; if ([[GSWApplication application] isCachingEnabled]) { if (archive) [_archiveCache setObject:archive forKey:relativePath]; else [_archiveCache setObject:GSNotFoundMarker forKey:relativePath]; }; }; }; NSDebugMLLog(@"bundles",@"archive=%@",archive); LOGObjectFnStop(); return archive; }; //-------------------------------------------------------------------- -(NSDictionary*)apiNamed:(NSString*)aName { //OK NSDictionary* api=nil; LOGObjectFnStart(); NSDebugMLLog(@"bundles",@"aName=%@",aName); [self lock]; NS_DURING { api=[self lockedApiNamed:aName]; NSDebugMLLog(@"bundles",@"api=%@",api); } NS_HANDLER { NSDebugMLLog(@"bundles",@"EXCEPTION:%@ (%@) [%s %d]", localException,[localException reason],__FILE__,__LINE__); //TODO [self unlock]; [localException raise]; }; NS_ENDHANDLER; [self unlock]; NSDebugMLLog(@"bundles",@"api=%@",api); LOGObjectFnStop(); return api; }; //-------------------------------------------------------------------- -(NSDictionary*)lockedApiNamed:(NSString*)aName { //OK NSDictionary* api=nil; NSString* relativePath=nil; NSString* absolutePath=nil; BOOL isCachingEnabled=NO; LOGObjectFnStart(); api=[self lockedResourceNamed:aName ofType:GSWAPISuffix withLanguages:nil usingCache:_apiCache relativePath:&relativePath absolutePath:&absolutePath]; if (!api) { if (absolutePath) { api=[NSDictionary dictionaryWithContentsOfFile:absolutePath]; if ([[GSWApplication application] isCachingEnabled]) { if (api) [_apiCache setObject:api forKey:relativePath]; else [_apiCache setObject:GSNotFoundMarker forKey:relativePath]; }; }; }; NSDebugMLLog(@"bundles",@"api=%@",api); LOGObjectFnStop(); return api; }; @end //==================================================================== @implementation GSWBundle (GSWBundleC) //-------------------------------------------------------------------- -(id)scriptedClassNameFromClassName:(NSString*)aName { LOGObjectFnNotImplemented(); //TODOFN return nil; }; //-------------------------------------------------------------------- -(id)scriptPathNameFromScriptedClassName:(NSString*)aName { LOGObjectFnNotImplemented(); //TODOFN return nil; }; @end