KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > derby > impl > services > monitor > TopService


1 /*
2
3    Derby - Class org.apache.derby.impl.services.monitor.TopService
4
5    Licensed to the Apache Software Foundation (ASF) under one or more
6    contributor license agreements. See the NOTICE file distributed with
7    this work for additional information regarding copyright ownership.
8    The ASF licenses this file to you under the Apache License, Version 2.0
9    (the "License"); you may not use this file except in compliance with
10    the License. You may obtain a copy of the License at
11
12       http://www.apache.org/licenses/LICENSE-2.0
13
14    Unless required by applicable law or agreed to in writing, software
15    distributed under the License is distributed on an "AS IS" BASIS,
16    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17    See the License for the specific language governing permissions and
18    limitations under the License.
19
20  */

21
22 package org.apache.derby.impl.services.monitor;
23
24 import org.apache.derby.iapi.services.monitor.ModuleControl;
25 import org.apache.derby.iapi.services.monitor.Monitor;
26
27 import org.apache.derby.iapi.services.monitor.PersistentService;
28 import org.apache.derby.iapi.error.StandardException;
29
30 import org.apache.derby.iapi.services.sanity.SanityManager;
31 import org.apache.derby.iapi.reference.SQLState;
32 import org.apache.derby.iapi.reference.EngineType;
33
34 import java.util.Hashtable JavaDoc;
35 import java.util.Vector JavaDoc;
36 import java.util.Properties JavaDoc;
37 import java.util.Locale JavaDoc;
38
39 /**
40     A description of an instance of a module.
41 */

42
43
44 final class TopService {
45
46     /*
47     ** Fields.
48     */

49
50     /**
51         The idenity of this service, note that it may not be active yet.
52     */

53     ProtocolKey key;
54
55     /**
56         The top module instance
57     */

58     ModuleInstance topModule;
59
60     /**
61         List of protocols.
62     */

63     Hashtable JavaDoc protocolTable;
64
65     /**
66     */

67     Vector JavaDoc moduleInstances;
68
69     /**
70     */

71     BaseMonitor monitor;
72
73     boolean inShutdown;
74
75     /**
76         The type of service this was created by. If null then this is a non-persistent service.
77     */

78     PersistentService serviceType;
79
80     Locale JavaDoc serviceLocale;
81
82     /*
83     ** Constructor
84     */

85
86
87     TopService(BaseMonitor monitor) {
88         super();
89         this.monitor = monitor;
90         protocolTable = new Hashtable JavaDoc();
91         moduleInstances = new Vector JavaDoc(0, 5);
92     }
93
94     TopService(BaseMonitor monitor, ProtocolKey key, PersistentService serviceType, Locale JavaDoc serviceLocale)
95     {
96         this(monitor);
97
98         this.key = key;
99         this.serviceType = serviceType;
100         this.serviceLocale = serviceLocale;
101     }
102
103     void setTopModule(Object JavaDoc instance) {
104         synchronized (this) {
105             for (int i = 0; i < moduleInstances.size(); i++) {
106                 ModuleInstance module = (ModuleInstance) moduleInstances.elementAt(i);
107                 if (module.getInstance() == instance) {
108                     topModule = module;
109                     notifyAll();
110                     break;
111                 }
112             }
113
114             // now add an additional entry into the hashtable
115
// that maps the server name as seen by the user
116
// onto the top module. This allows modules to find their
117
// top most service moduel using the monitor.getServiceName() call,
118
// e.g. Monitor.findModule(ref, inferface, Monitor.getServiceName(ref));
119
if (getServiceType() != null) {
120                 ProtocolKey userKey = new ProtocolKey(key.getFactoryInterface(),
121                     monitor.getServiceName(instance));
122                 addToProtocol(userKey, topModule);
123             }
124
125         }
126     }
127
128     Object JavaDoc getService() {
129
130         return topModule.getInstance();
131     }
132
133     boolean isPotentialService(ProtocolKey otherKey) {
134
135
136         String JavaDoc otherCanonicalName;
137
138         if (serviceType == null)
139             otherCanonicalName = otherKey.getIdentifier();
140         else {
141             try
142             {
143                 otherCanonicalName = serviceType.getCanonicalServiceName(otherKey.getIdentifier());
144             } catch (StandardException se)
145             {
146                 return false;
147             }
148
149             // if the service name cannot be converted into a canonical name then it is not a service.
150
if (otherCanonicalName == null)
151                 return false;
152         }
153
154         if (topModule != null)
155             return topModule.isTypeAndName(serviceType, key.getFactoryInterface(), otherCanonicalName);
156
157
158         if (!otherKey.getFactoryInterface().isAssignableFrom(key.getFactoryInterface()))
159             return false;
160
161         return serviceType.isSameService(key.getIdentifier(), otherCanonicalName);
162     }
163
164     boolean isActiveService() {
165         synchronized (this) {
166             return (topModule != null);
167         }
168     }
169
170     boolean isActiveService(ProtocolKey otherKey) {
171
172         synchronized (this) {
173             if (inShutdown)
174                 return false;
175
176             if (!isPotentialService(otherKey))
177                 return false;
178
179             if (topModule != null) {
180                 if (SanityManager.DEBUG) {
181                     SanityManager.ASSERT(topModule.isTypeAndName(serviceType,
182                         key.getFactoryInterface(), key.getIdentifier()));
183                 }
184
185                 return true;
186             }
187
188             // now wait for topModule to be set
189
while (!inShutdown && (topModule == null)) {
190                 try {
191                     wait();
192                 } catch (InterruptedException JavaDoc ioe) {
193                     return false;
194                 }
195             }
196
197             if (inShutdown)
198                 return false;
199
200             return true;
201         }
202     }
203
204     /**
205         Find an module in the protocol table that supports the required protocol
206         name combination and can handle the properties.
207
208         Returns the instance of the module or null if one does not exist in
209         the protocol table.
210     */

211     synchronized Object JavaDoc findModule(ProtocolKey key, boolean findOnly, Properties JavaDoc properties) {
212
213         ModuleInstance module = (ModuleInstance) protocolTable.get(key);
214
215         if (module == null)
216             return null;
217
218         Object JavaDoc instance = module.getInstance();
219
220         if (findOnly || BaseMonitor.canSupport(instance, properties))
221             return instance;
222
223         return null;
224     }
225
226     /**
227         Boot a module, performs three steps.
228
229         <OL>
230         <LI> Look for an existing module in the protocol table
231         <LI> Look for a module in the implementation table that handles this protocol
232         <LI> Create an instance that handles this protocol.
233         </OL>
234     */

235     Object JavaDoc bootModule(boolean create, Object JavaDoc service, ProtocolKey key, Properties JavaDoc properties)
236         throws StandardException {
237
238         synchronized (this) {
239             if (inShutdown)
240                 throw StandardException.newException(SQLState.SHUTDOWN_DATABASE, getKey().getIdentifier());
241         }
242
243         // see if this system already has a module that will work.
244
Object JavaDoc instance = findModule(key, false, properties);
245         if (instance != null)
246             return instance;
247         
248         if (monitor.reportOn) {
249             monitor.report("Booting Module " + key.toString() + " create = " + create);
250         }
251
252         // see if a running implementation will handle this protocol
253
synchronized (this) {
254
255             for (int i = 0; i < moduleInstances.size(); i++) {
256                 ModuleInstance module = (ModuleInstance) moduleInstances.elementAt(i);
257
258                 if (!module.isTypeAndName((PersistentService) null, key.getFactoryInterface(), key.getIdentifier()))
259                     continue;
260
261                 instance = module.getInstance();
262                 if (!BaseMonitor.canSupport(instance, properties))
263                     continue;
264
265                 // add it to the protocol table, if this returns false then we can't use
266
// this module, continue looking.
267
if (!addToProtocol(key, module))
268                     continue;
269
270                 if (monitor.reportOn) {
271                     monitor.report("Started Module " + key.toString());
272                     monitor.report(" Implementation " + instance.getClass().getName());
273                 }
274
275                 return instance;
276             }
277         }
278
279         // try and load an instance that will support this protocol
280
instance = monitor.loadInstance(key.getFactoryInterface(), properties);
281         if (instance == null)
282         {
283             throw Monitor.missingImplementation(key.getFactoryInterface().getName());
284         }
285         ModuleInstance module = new ModuleInstance(instance, key.getIdentifier(), service,
286                 topModule == null ? (Object JavaDoc) null : topModule.getInstance());
287
288         moduleInstances.addElement(module);
289
290         try {
291             BaseMonitor.boot(instance, create, properties);
292         } catch (StandardException se) {
293             moduleInstances.removeElement(module);
294             throw se;
295         }
296
297         synchronized (this) {
298
299
300             // add it to the protocol table, if this returns false then we can't use
301
// this module, shut it down.
302
if (addToProtocol(key, module)) {
303
304                 if (monitor.reportOn) {
305                     monitor.report("Started Module " + key.toString());
306                     monitor.report(" Implementation " + module.getInstance().getClass().getName());
307                 }
308
309                 return module.getInstance();
310             }
311
312             
313         }
314     
315         TopService.stop(instance);
316         moduleInstances.removeElement(module);
317
318         // if we reached here it's because someone else beat us adding the module, so use theirs.
319
return findModule(key, true, properties);
320     }
321
322     /**
323         If the service is already beign shutdown we return false.
324     */

325     boolean shutdown() {
326
327         synchronized (this) {
328             if (inShutdown)
329                 return false;
330
331             inShutdown = true;
332             notifyAll();
333         }
334
335         for (;;) {
336
337             ModuleInstance module;
338
339             synchronized (this) {
340
341                 if (moduleInstances.isEmpty())
342                     return true;
343
344                 module = (ModuleInstance) moduleInstances.elementAt(0);
345
346             }
347             
348             Object JavaDoc instance = module.getInstance();
349             TopService.stop(instance);
350             
351             synchronized (this) {
352                 moduleInstances.removeElementAt(0);
353             }
354         }
355     }
356
357     /**
358         Add a running module into the protocol hash table. Return true
359         if the module was added successfully, false if it couldn't
360         be added. In the latter case the module should be shutdown
361         if its reference count is 0.
362     */

363
364     private boolean addToProtocol(ProtocolKey key, ModuleInstance module) {
365
366         String JavaDoc identifier = module.getIdentifier();
367
368         synchronized (this) {
369
370             Object JavaDoc value = protocolTable.get(key);
371             if (value == null) {
372
373                 protocolTable.put(key, module);
374                 return true;
375             }
376
377             if (value == module)
378                 return true;
379
380             return false;
381         }
382     }
383
384     boolean inService(Object JavaDoc instance) {
385
386         for (int i = 0; i < moduleInstances.size(); i++) {
387
388             ModuleInstance mi = (ModuleInstance) moduleInstances.elementAt(i);
389             if (mi.getInstance() == instance)
390                 return true;
391         }
392         return false;
393     }
394
395     public ProtocolKey getKey() {
396         return key;
397     }
398
399     PersistentService getServiceType() {
400         return serviceType;
401     }
402
403     private static void stop(Object JavaDoc instance) {
404         if (instance instanceof ModuleControl) {
405             ((ModuleControl) instance).stop();
406         }
407     }
408 }
409
Popular Tags