1/*! 2 @header FTDefaultServiceManagerImpl 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 28.09.05 ola initial version 27 23.08.06 ola license changed 28 ------------------------------------------------------------------------- 29 </pre> 30*/ 31 32#include <FT/FTDefaultServiceManagerImpl.h> 33#include <FT/FTServiceLoader.h> 34#include <FT/FTDefaultServiceEnvironment.h> 35#include <FT/FTLogging.h> 36 37@implementation FTDefaultServiceManagerImpl 38 39- initWithServer: (FTServerImpl *) aServer { 40 self = [super init]; 41 42 self->serviceIdToServiceLoader = [[NSMutableDictionary alloc] init]; 43 self->rwLock = [[NSLock alloc] init]; 44 self->server = [aServer retain]; 45 46 return self; 47} 48 49 50- (void) dealloc { 51 if( nil != self->serviceIdToServiceLoader ) { 52 [self->serviceIdToServiceLoader release]; 53 } 54 55 if( nil != self->rwLock ) { 56 [self->rwLock release]; 57 } 58 59 if( nil != self->server ) { 60 [self->server release]; 61 } 62 63 [super dealloc]; 64} 65 66 67- (id <ECIterator>) allServicesForGraph: (id <FTGraph>) aGraph { 68 return [self allServicesForNode: nil ofGraph: aGraph]; 69} 70 71 72- (id <ECIterator>) allServicesForNode: (id <FTNode>) aNode 73 ofGraph: (id <FTGraph>) aGraph { 74 75 NSMutableArray *availServices = [[[NSMutableArray alloc] init] autorelease]; 76 NSArray *allServices; 77 int i; 78 ECArrayIterator *toReturn; 79 BOOL isAvailable; 80 BOOL checkForNode = nil != aNode; 81 82 EC_AUTORELEASEPOOL_BEGIN 83 84 allServices = [self->serviceIdToServiceLoader allValues]; 85 86 for( i = 0; i < [allServices count]; i++ ) { 87 id <FTServiceAvailability> availability; 88 89 NS_DURING 90 availability = [[allServices objectAtIndex: i] serviceAvailability]; 91 92 if( checkForNode ) { 93 isAvailable = [availability availableForNode: aNode 94 ofGraph: aGraph]; 95 } else { 96 isAvailable = [availability availableForGraph: aGraph]; 97 } 98 99 if( isAvailable ) { 100 if( checkForNode ) { 101 [availServices addObject: 102 [[allServices objectAtIndex: i ] serviceForNode: aNode 103 ofGraph: aGraph]]; 104 } else { 105 [availServices addObject: 106 [[allServices objectAtIndex: i ] serviceForGraph: aGraph]]; 107 } 108 } 109 NS_HANDLER 110 //ignore this exception and proceed 111 NS_ENDHANDLER 112 } 113 114 toReturn = [[ECArrayIterator alloc] initWithArray: availServices]; 115 116 EC_AUTORELEASEPOOL_END 117 118 return toReturn; 119} 120 121 122 123- registerServiceWithId: (NSString *) serviceId 124 withVersion: (id <FTVersion>) serviceVersion 125 withServiceLoader: (id <FTServiceLoader>) serviceLoader { 126 id <FTServiceLoader> tmp; 127 128 EC_AUTORELEASEPOOL_BEGIN 129 [self rwLock]; 130 131 tmp = [self->serviceIdToServiceLoader objectForKey: serviceId]; 132 133 if( nil != tmp ) { 134 if( [[tmp serviceVersion] isEqual: serviceVersion] ) { 135 [self rwUnlock]; 136 137 [[[ECAlreadyExistsException alloc] 138 initWithResourceInformation: 139 [[NSString alloc] initWithFormat: @"Service \"%@\" already exists "\ 140 "with service id=\"%@\" and version=\"%@\"", 141 tmp, serviceId, serviceVersion]] raise]; 142 } else { 143 [self unregisterAllVersionsOfServiceWithId: serviceId]; 144 tmp = nil; 145 } 146 } 147 148 [self->serviceIdToServiceLoader setObject: serviceLoader forKey: serviceId]; 149 150 [serviceLoader setEnvironment: 151 [[FTDefaultServiceEnvironment alloc] initWithServer: self->server]]; 152 153 [self rwUnlock]; 154 155 EC_AUTORELEASEPOOL_END 156 return self; 157} 158 159 160- rwLock { 161 [self->rwLock lock]; 162 163 return self; 164} 165 166 167- rwUnlock { 168 [self->rwLock unlock]; 169 170 return self; 171} 172 173 174 175- (id <FTService>) serviceWithId: (NSString *) aServiceId 176 forGraph: (id <FTGraph>) aGraph { 177 178 return [self serviceWithId: aServiceId forGraph: aGraph forNode: nil]; 179} 180 181 182- (id <FTService>) serviceWithId: (NSString *) aServiceId 183 forGraph: (id <FTGraph>) aGraph forNode: (id <FTNode>) aNode { 184 id <FTService> toReturn = nil; 185 186 id <FTServiceLoader> serviceLoader 187 = [self->serviceIdToServiceLoader objectForKey: aServiceId]; 188 189 NS_DURING 190 if( nil != serviceLoader ) { 191 if( nil != aNode ) { 192 toReturn = [serviceLoader serviceForNode: aNode ofGraph: aGraph]; 193 } else { 194 toReturn = [serviceLoader serviceForGraph: aGraph]; 195 } 196 } 197 NS_HANDLER 198 //ignore it 199 NS_ENDHANDLER 200 201 return toReturn; 202} 203 204 205- switchAllServicesToMode: (ft_serviceMode_t) serviceMode { 206 NSEnumerator *serviceLoaders = [serviceIdToServiceLoader objectEnumerator]; 207 id current; 208 209 EC_AUTORELEASEPOOL_BEGIN 210 while( (current = [serviceLoaders nextObject]) ) { 211 NS_DURING 212 if( [[FTLogging coreLog] isDebugEnabled] ) { 213 [[FTLogging coreLog] 214 debug: @"FTDefaultServiceManagerImpl::switchAllServicesToMode: "\ 215 "Switching mode of service: %@", current ]; 216 } 217 [current switchToMode: serviceMode]; 218 NS_HANDLER 219 [[FTLogging coreLog] 220 error: @"FTDefaultServiceManagerImpl::switchAllServicesToMode: "\ 221 "Switching mode of service \"%@\" FAILED! Ignoring it...", current ]; 222 NS_ENDHANDLER 223 } 224 EC_AUTORELEASEPOOL_END 225 226 return self; 227} 228 229 230- unregisterAllVersionsOfServiceWithId: (NSString *) serviceId { 231 [self->serviceIdToServiceLoader removeObjectForKey: serviceId]; 232 233 return self; 234} 235@end 236