1/*! 2 @header FTDictionaryServiceLoader 3 @abstract Module of FT 4 5 @availability OS X, GNUstep 6 @copyright 2004, 2005, 2006 Free Software Foundation, Inc. 7 8 This library is free software; you can redistribute it and/or 9 modify it under the terms of the GNU Lesser General Public 10 License as published by the Free Software Foundation; either 11 version 2.1 of the License, or (at your option) any later version. 12 13 This library is distributed in the hope that it will be useful, 14 but WITHOUT ANY WARRANTY; without even the implied warranty of 15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 16 Lesser General Public License for more details. 17 18 You should have received a copy of the GNU Lesser General Public 19 License along with this library; if not, write to the Free Software 20 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 21 22 <pre> 23 ------------------------------------------------------------------------- 24 Modification history 25 26 21.09.05 ola initial version 27 16.07.06 ola new implementation 28 23.08.06 ola license changed 29 ------------------------------------------------------------------------- 30 </pre> 31*/ 32 33#include <FT/FTDictionaryServiceStorageException.h> 34#include <FT/FTDictionaryServiceLoader.h> 35#include <FT/FTDictionaryService.h> 36#include <FT/FTVersionImpl.h> 37#include <FT/FTLogging.h> 38#include "FTDictionaryServiceForGraphImpl.h" 39#include <FTNotifications.h> 40 41#define __VERSION_MAJOR 0 42#define __VERSION_MINOR 2 43#define __VERSION_BUILD 1 44#define __VERSION_STATE FT_VERSION_SNAPSHOT 45 46#define __FTDictionaryServiceId @"FTDictionaryService" 47#define __FTDictionaryServiceDataDirectory @"FTDictionaryServiceData" 48#define __FTDictionaryIndexDB @"DictionaryIndex.db" 49 50@implementation FTDictionaryServiceLoader 51 52- init { 53 self = [super init]; 54 self->serviceVersion = [[FTVersionImpl alloc] 55 initWithMajor: __VERSION_MAJOR 56 withMinor: __VERSION_MINOR 57 withBuild: __VERSION_BUILD 58 asState: __VERSION_STATE]; 59 60 self->serviceAvailability = [[FTDictionaryServiceAvailability alloc] init]; 61 self->serviceEnvironment = nil; 62 63 self->graphToServiceImpl = nil; 64 self->generalLock = [[NSLock alloc] init]; 65 66 return self; 67} 68 69 70- (void) dealloc { 71 [self->generalLock release]; 72 73 if( nil != self->serviceVersion ) { 74 [self->serviceVersion release]; 75 } 76 77 if( nil != self->serviceAvailability ) { 78 [self->serviceAvailability release]; 79 } 80 81 if( nil != self->serviceEnvironment ) { 82 [self->serviceEnvironment release]; 83 } 84 85 86 [self->databaseNameScheme release]; 87 88 [super dealloc]; 89} 90 91 92- (NSString *) databaseNameScheme { 93 return self->databaseNameScheme; 94} 95 96 97- onGraphClosed: (NSNotification *) notification { 98 FTDictionaryServiceForGraphImpl *serviceImpl; 99 FTGraphImpl *graphImpl; 100 unsigned cnt; 101 102 graphImpl = [notification object]; 103 104 if( [[FTLogging coreLog] isTraceEnabled] ) { 105 [[FTLogging coreLog] 106 trace: @"FTDictionaryServiceLoader::onGraphClosed"]; 107 } 108 109 serviceImpl = [[self->graphToServiceImpl 110 objectForKey: [graphImpl graphId] 111 incrementRefCounter: NO] retain]; 112 113 NS_DURING 114 115 cnt = [self->graphToServiceImpl 116 referenceCounterOfObjectForKey: [graphImpl graphId]] ; 117 if( nil != serviceImpl ) { 118 [self->graphToServiceImpl 119 decrementRefCounterForKey: [graphImpl graphId]]; 120 cnt = [self->graphToServiceImpl 121 referenceCounterOfObjectForKey: [graphImpl graphId]] ; 122 if(0 == cnt ) { 123 [[NSNotificationCenter defaultCenter] 124 removeObserver: self]; 125 [serviceImpl close]; 126 } 127 } else { 128 [[NSNotificationCenter defaultCenter] 129 removeObserver: self]; 130 } 131 NS_HANDLER 132 [serviceImpl release]; 133 [localException raise]; 134 NS_ENDHANDLER 135 136 [serviceImpl release]; 137 return self; 138} 139 140 141- (id <FTServiceAvailability>) serviceAvailability { 142 return self->serviceAvailability; 143} 144 145 146- (id <FTService>) serviceForGraph: (id <FTGraph>) aGraph { 147 148 return nil; 149} 150 151 152- (id <FTService>) serviceForNode: (id <FTNode>) aNode 153 ofGraph: (id <FTGraph>) aGraph { 154 FTDictionaryServiceForGraphImpl *serviceImpl; 155 156 [self->generalLock lock]; 157 158 serviceImpl = [self->graphToServiceImpl 159 objectForKey: [aGraph graphId] 160 incrementRefCounter: NO]; 161 162 if( nil == serviceImpl ) { 163 NS_DURING 164 serviceImpl = [[FTDictionaryServiceForGraphImpl alloc] 165 initForGraph: aGraph 166 serviceLoader: self]; 167 [self->graphToServiceImpl 168 addObject: serviceImpl 169 forKey: [aGraph graphId]]; 170 171 [[NSNotificationCenter defaultCenter] 172 addObserver: self 173 selector: @selector(onGraphClosed:) 174 name: FTNotification_Graph_afterClosed 175 object: nil]; 176 NS_HANDLER 177 [self->generalLock unlock]; 178 [[FTLogging coreLog] 179 error: @"FTDictionaryServiceLoader::serviceForNode: Unable to create "\ 180 "new dictionary service instance due to exception: %@", 181 localException]; 182 [localException raise]; 183 NS_ENDHANDLER 184 } 185 186 [self->generalLock unlock]; 187 188 return [serviceImpl serviceForNode: aNode]; 189} 190 191 192- (NSString *) serviceId { 193 return __FTDictionaryServiceId; 194} 195 196 197- (id <FTVersion>) serviceVersion { 198 return self->serviceVersion; 199} 200 201 202- setDatabaseNameSchema: (NSString *) aDatabaseName { 203 [aDatabaseName retain]; 204 205 [self->databaseNameScheme release]; 206 self->databaseNameScheme = aDatabaseName; 207 208 return self; 209 210} 211 212 213- setEnvironment: (id <FTServiceEnvironment>) aServiceEnvironment { 214 if( nil != self->serviceEnvironment ) { 215 [self->serviceEnvironment release]; 216 } 217 218 self->serviceEnvironment = [aServiceEnvironment retain]; 219 220 return self; 221} 222 223 224- switchToMode: (ft_serviceMode_t) aServiceMode { 225 id <ECIterator> allKeys; 226 id <FTDictionaryService> currentService; 227 id graphId; 228 229 switch( aServiceMode ) { 230 case FT_SERVICE_MODE_ONLINE: 231 [self->graphToServiceImpl release]; 232 self->graphToServiceImpl = [[ECCache alloc] init]; 233 break; 234 case FT_SERVICE_MODE_SHUTDOWN: 235 /* close all dictionaries: */ 236 allKeys = [self->graphToServiceImpl allKeys]; 237 while( [allKeys hasNext] ) { 238 graphId = [allKeys next]; 239 currentService = [self->graphToServiceImpl 240 objectForKey: [allKeys next] 241 incrementRefCounter: NO]; 242 NS_DURING 243 [currentService close]; 244 NS_HANDLER 245 [[FTLogging coreLog] 246 error: @"FTDictionaryServiceLoader::switchToMode: Unable to close "\ 247 "dictionary identified by: %@", graphId]; 248 NS_ENDHANDLER 249 } 250 251 [self->graphToServiceImpl release]; 252 self->graphToServiceImpl = nil; 253 break; 254 default: 255 [[FTLogging coreLog] 256 error: @"FTDictionaryServiceLoader::switchToMode: "\ 257 "Unknown mode=%u given. Ignoring it.", (unsigned) aServiceMode]; 258 259 } 260 return self; 261} 262 263 264@end 265 266 267@implementation FTDictionaryServiceAvailability 268 269- (BOOL) availableForGraph: (id <FTGraph>) aGraph { 270 return nil != aGraph; 271} 272 273 274- (BOOL) availableForNodesOfGraph: (id <FTGraph>) aGraph { 275 return nil != aGraph; 276} 277 278 279- (BOOL) availableForNode: (id <FTNode>) aNode ofGraph: (id <FTGraph>) aGraph { 280 return ((nil != aNode) && (nil != aGraph)); 281} 282@end 283 284