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