KickJava   Java API By Example, From Geeks To Geeks.

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


1 /*
2
3    Derby - Class org.apache.derby.impl.services.monitor.BaseMonitor
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.Monitor;
25 import org.apache.derby.iapi.services.monitor.ModuleFactory;
26 import org.apache.derby.iapi.services.monitor.ModuleControl;
27 import org.apache.derby.iapi.services.monitor.ModuleSupportable;
28
29 import org.apache.derby.iapi.services.monitor.PersistentService;
30
31 import org.apache.derby.iapi.services.io.FormatIdUtil;
32 import org.apache.derby.iapi.services.io.RegisteredFormatIds;
33 import org.apache.derby.iapi.services.io.StoredFormatIds;
34
35 import org.apache.derby.iapi.services.context.ContextManager;
36 import org.apache.derby.iapi.services.context.Context;
37 import org.apache.derby.iapi.services.context.ContextService;
38 import org.apache.derby.iapi.services.context.ShutdownException;
39
40 import org.apache.derby.iapi.services.stream.InfoStreams;
41 import org.apache.derby.iapi.services.stream.PrintWriterGetHeader;
42
43 import org.apache.derby.iapi.services.sanity.SanityManager;
44 import org.apache.derby.iapi.error.StandardException;
45 import org.apache.derby.iapi.services.uuid.UUIDFactory;
46 import org.apache.derby.iapi.services.timer.TimerFactory;
47 import org.apache.derby.iapi.reference.Property;
48 import org.apache.derby.iapi.reference.SQLState;
49 import org.apache.derby.iapi.reference.Attribute;
50 import org.apache.derby.iapi.services.property.PropertyUtil;
51
52 import org.apache.derby.iapi.services.io.AccessibleByteArrayOutputStream;
53 import org.apache.derby.iapi.services.loader.ClassInfo;
54 import org.apache.derby.iapi.services.loader.InstanceGetter;
55 import org.apache.derby.iapi.services.io.FormatableInstanceGetter;
56 import org.apache.derby.iapi.error.ExceptionSeverity;
57
58 import org.apache.derby.io.StorageFactory;
59
60 import org.apache.derby.iapi.services.context.ErrorStringBuilder;
61
62 import org.apache.derby.iapi.services.info.JVMInfo;
63 import org.apache.derby.iapi.services.i18n.BundleFinder;
64 import org.apache.derby.iapi.services.i18n.MessageService;
65
66 import org.apache.derby.impl.services.monitor.StorageFactoryService;
67
68 import java.io.IOException JavaDoc;
69 import java.io.InputStream JavaDoc;
70 import java.io.StringWriter JavaDoc;
71 import java.io.BufferedInputStream JavaDoc;
72 import java.io.PrintWriter JavaDoc;
73 import java.io.BufferedReader JavaDoc;
74 import java.io.InputStreamReader JavaDoc;
75 import java.io.ByteArrayInputStream JavaDoc;
76 import java.io.PrintStream JavaDoc;
77
78 import java.util.Hashtable JavaDoc;
79 import java.util.HashMap JavaDoc;
80 import java.util.Properties JavaDoc;
81 import java.util.Enumeration JavaDoc;
82 import java.util.StringTokenizer JavaDoc;
83 import java.util.Vector JavaDoc;
84 import java.util.Locale JavaDoc;
85 import java.util.ResourceBundle JavaDoc;
86 import java.util.NoSuchElementException JavaDoc;
87
88 import java.lang.reflect.Method JavaDoc;
89 import java.lang.reflect.Modifier JavaDoc;
90 import java.lang.reflect.InvocationTargetException JavaDoc;
91
92 import java.security.AccessController JavaDoc;
93 import java.security.PrivilegedExceptionAction JavaDoc;
94 import java.security.PrivilegedActionException JavaDoc;
95
96 import java.net.URL JavaDoc;
97
98 /**
99     Implementation of the monitor that uses the class loader
100     that the its was loaded in for all class loading.
101
102 */

103
104 abstract class BaseMonitor
105     implements ModuleFactory, BundleFinder {
106
107     /* Fields */
108
109     /**
110         Hashtable of objects that implement PersistentService keyed by their getType() method.
111     */

112     Hashtable JavaDoc serviceProviders;
113
114     // Vector of class objects of implementations, found in the System, application
115
// and default (modules.properties) properties
116

117     Vector JavaDoc[] implementationSets;
118
119     private Vector JavaDoc services; // Vector of TopServices
120

121     Properties JavaDoc bootProperties; // specifc properties provided by the boot method, override everything else
122
Properties JavaDoc applicationProperties;
123
124     boolean inShutdown;
125
126     // Here are the list of modules that we always boot
127
private InfoStreams systemStreams;
128     private ContextService contextService;
129     private UUIDFactory uuidFactory;
130     private TimerFactory timerFactory;
131
132     boolean reportOn;
133     private PrintStream JavaDoc logging;
134
135     ThreadGroup JavaDoc daemonGroup;
136
137     // anti GC stuff
138
AntiGC dontGC;
139
140     // class registry
141
/* one byte format identifiers never used
142     private InstanceGetter[] rc1;
143 */

144     private InstanceGetter[] rc2;
145 // private InstanceGetter[] rc4;
146

147     /* Constructor */
148     BaseMonitor() {
149         super();
150
151         services = new Vector JavaDoc(0, 1);
152         services.addElement(new TopService(this)); // first element is always the free-floating service
153
}
154
155     /* Methods of ModuleFactory includes BootStrap and Runnable */
156
157     public InfoStreams getSystemStreams() {
158         return systemStreams;
159     }
160
161     public void shutdown() {
162
163         // allow only one caller to shut the monitor down
164
synchronized (this) {
165             if (inShutdown)
166                 return;
167             inShutdown = true;
168         }
169
170         if (SanityManager.DEBUG && reportOn) {
171             report("Shutdown request");
172         }
173
174         // Shutdown all threads by iterrupting them
175
contextService.notifyAllActiveThreads((Context) null);
176
177         for (;;) {
178
179             TopService ts;
180             int position;
181             synchronized (this) {
182                 position = services.size() - 1;
183                 if (position == 0)
184                     break;
185
186                 ts = (TopService) services.elementAt(position);
187             }
188
189             // push a new context manager
190
ContextManager cm = contextService.newContextManager();
191             try {
192                 // pop the default shutdown context, we are shutting down
193
cm.popContext();
194
195                 contextService.setCurrentContextManager(cm);
196
197
198                 shutdown(ts.getService());
199
200             } finally {
201                 contextService.resetCurrentContextManager(cm);
202             }
203
204         }
205         ((TopService) services.elementAt(0)).shutdown();
206
207         synchronized (dontGC) {
208
209             dontGC.goAway = true;
210             dontGC.notifyAll();
211         }
212
213         ContextService.stop();
214         Monitor.clearMonitor();
215     }
216
217     /**
218         Shut down a service that was started by this Monitor. Will
219         cause the stop() method to be called on each loaded module.
220     */

221     public void shutdown(Object JavaDoc serviceModule) {
222         if (serviceModule == null)
223             return;
224
225         TopService ts = findTopService(serviceModule);
226         if (ts == null)
227             return;
228
229         // shutdown() returns false if the service is already being shutdown
230
boolean removeService = true;
231         try {
232             removeService = ts.shutdown();
233         } finally {
234             synchronized (this) {
235                 if (removeService) {
236                     boolean found = services.removeElement(ts);
237                     if (SanityManager.DEBUG) {
238                         SanityManager.ASSERT(found, "service was not found " + serviceModule);
239                     }
240                 }
241             }
242         }
243     }
244
245     protected final void runWithState(Properties JavaDoc properties, PrintStream JavaDoc log) {
246
247         bootProperties = properties;
248         logging = log;
249
250         // false indicates the full monitor is required, not the lite.
251
if (!initialize(false))
252             return;
253
254         // if monitor is already set then the system is already
255
// booted or in the process of booting or shutting down.
256
if (!Monitor.setMonitor(this))
257             return;
258
259         Object JavaDoc msgService = MessageService.setFinder(this);
260
261         // start a backgorund thread which keeps a reference to this
262
// this monitor, and an instance of the Monitor class to ensure
263
// that the monitor instance and the class is not garbage collected
264
// See Sun's bug 4057924 in Java Developer Section 97/08/06
265

266         Object JavaDoc[] keepItems = new Object JavaDoc[3];
267         keepItems[0] = this;
268         keepItems[1] = new Monitor();
269         keepItems[2] = msgService;
270         dontGC = new AntiGC(keepItems);
271
272         Thread JavaDoc dontGCthread = getDaemonThread(dontGC, "antiGC", true);
273         dontGCthread.start();
274
275         if (SanityManager.DEBUG) {
276             reportOn = Boolean.valueOf(PropertyUtil.getSystemProperty("derby.monitor.verbose")).booleanValue();
277         }
278
279         // Set up the application properties
280
applicationProperties = readApplicationProperties();
281
282         // The security manager may not let us get the System properties
283
// object itself, although it may let us look at the properties in it.
284
Properties JavaDoc systemProperties = null;
285
286         if (SanityManager.DEBUG) {
287             // In a production system having this call would
288
// mean would we have to document it for security
289
// permission reasons. Since we don't require it and
290
// its a big security hole to allow external code to
291
// overwrite our own implementations we just support
292
// it for debugging. This means VM executions such as
293
// java -Dderby.module.javaCompiler=com.ibm.db2j.impl.BasicServices.JavaCompiler.JavaLang.JLJava ...
294
// would only work with a sane codeline.
295
try {
296                 systemProperties = System.getProperties();
297             } catch (SecurityException JavaDoc se) {
298             }
299         }
300
301         Vector JavaDoc bootImplementations = getImplementations(bootProperties, false);
302
303         Vector JavaDoc systemImplementations = null;
304         Vector JavaDoc applicationImplementations = null;
305
306         // TEMP - making this sanity only breaks the unit test code
307
// I will fix soon, djd.
308
if (true || SanityManager.DEBUG) {
309             // Don't allow external code to override our implementations.
310
systemImplementations = getImplementations(systemProperties, false);
311             applicationImplementations = getImplementations(applicationProperties, false);
312         }
313
314         Vector JavaDoc defaultImplementations = getDefaultImplementations();
315
316         int implementationCount = 0;
317         if (bootImplementations != null)
318             implementationCount++;
319
320         // TEMP - making this sanity only breaks the unit test code
321
if (true || SanityManager.DEBUG) {
322             // Don't allow external code to override our implementations.
323
if (systemImplementations != null)
324                 implementationCount++;
325             if (applicationImplementations != null)
326                 implementationCount++;
327         }
328
329         if (defaultImplementations != null)
330             implementationCount++;
331         implementationSets = new Vector JavaDoc[implementationCount];
332
333         implementationCount = 0;
334         if (bootImplementations != null)
335             implementationSets[implementationCount++] = bootImplementations;
336         
337         if (true || SanityManager.DEBUG) {
338             // Don't allow external code to override our implementations.
339
if (systemImplementations != null)
340                 implementationSets[implementationCount++] = systemImplementations;
341             if (applicationImplementations != null)
342                 implementationSets[implementationCount++] = applicationImplementations;
343         }
344
345         if (defaultImplementations != null)
346             implementationSets[implementationCount++] = defaultImplementations;
347
348
349         if (SanityManager.DEBUG) {
350             // Look for the derby.debug.* properties.
351
if (applicationProperties != null) {
352                 addDebugFlags(applicationProperties.getProperty(Monitor.DEBUG_FALSE), false);
353                 addDebugFlags(applicationProperties.getProperty(Monitor.DEBUG_TRUE), true);
354             }
355
356             addDebugFlags(PropertyUtil.getSystemProperty(Monitor.DEBUG_FALSE), false);
357             addDebugFlags(PropertyUtil.getSystemProperty(Monitor.DEBUG_TRUE), true);
358         }
359
360         try {
361             systemStreams = (InfoStreams) Monitor.startSystemModule("org.apache.derby.iapi.services.stream.InfoStreams");
362
363             if (SanityManager.DEBUG) {
364                 SanityManager.SET_DEBUG_STREAM(systemStreams.stream().getPrintWriter());
365             }
366
367             contextService = new ContextService();
368
369             uuidFactory = (UUIDFactory) Monitor.startSystemModule("org.apache.derby.iapi.services.uuid.UUIDFactory");
370
371             timerFactory = (TimerFactory)Monitor.startSystemModule("org.apache.derby.iapi.services.timer.TimerFactory");
372         } catch (StandardException se) {
373
374             // if we can't create an error log or a context then there's no point going on
375
reportException(se);
376             // dump any messages we have been saving ...
377
dumpTempWriter(true);
378
379             return;
380         }
381
382         // switch cover to the real error stream and
383
// dump any messages we have been saving ...
384
dumpTempWriter(false);
385
386         if (SanityManager.DEBUG && reportOn) {
387             dumpProperties("-- Boot Properties --", bootProperties);
388             dumpProperties("-- System Properties --", systemProperties);
389             dumpProperties("-- Application Properties --", applicationProperties);
390         }
391
392         // bootup all the service providers
393
bootServiceProviders();
394
395         // See if automatic booting of persistent services is required
396
boolean bootAll = Boolean.valueOf(PropertyUtil.getSystemProperty(Property.BOOT_ALL)).booleanValue();
397
398
399         startServices(bootProperties, bootAll);
400         startServices(systemProperties, bootAll);
401         startServices(applicationProperties, bootAll);
402
403         if (bootAll) // only if automatic booting is required
404
bootPersistentServices( );
405     }
406
407     public Object JavaDoc findService(String JavaDoc factoryInterface, String JavaDoc serviceName) {
408
409         if (serviceName == null)
410             return null;
411
412         ProtocolKey key;
413
414         try {
415             key = ProtocolKey.create(factoryInterface, serviceName);
416         } catch (StandardException se) {
417             return null;
418         }
419
420         TopService myts = null;
421         synchronized (this) {
422             for (int i = 1; i < services.size(); i++) {
423                 TopService ts = (TopService) services.elementAt(i);
424                 if (ts.isPotentialService(key)) {
425                     myts = ts;
426                     break;
427                 }
428             }
429         }
430
431         // the isActiveService() call may sleep
432
// so don't hold the 'this' synchronization
433
if (myts != null) {
434             if (myts.isActiveService(key))
435                 return myts.getService();
436         }
437
438         return null;
439     }
440
441     public Locale JavaDoc getLocale(Object JavaDoc serviceModule) {
442
443         TopService ts = findTopService(serviceModule);
444
445         if (ts == null)
446             return null;
447
448         return ts.serviceLocale;
449
450     }
451
452     public Locale JavaDoc getLocaleFromString(String JavaDoc localeDescription)
453                                             throws StandardException {
454         return staticGetLocaleFromString(localeDescription);
455     }
456
457     /**
458         Return the name of the service that the passed in module lives in.
459     */

460     public String JavaDoc getServiceName(Object JavaDoc serviceModule) {
461
462         TopService ts = findTopService(serviceModule);
463
464         if (ts == null)
465             return null;
466
467         return ts.getServiceType().getUserServiceName(ts.getKey().getIdentifier());
468     }
469
470     /**
471         Set the locale for the service *outside* of boot time.
472
473         @exception StandardException Standard Cloudscape error.
474     */

475     public Locale JavaDoc setLocale(Object JavaDoc serviceModule, String JavaDoc userDefinedLocale)
476         throws StandardException {
477
478         TopService ts = findTopService(serviceModule);
479
480         if (ts == null)
481             return null;
482
483         PersistentService provider = ts.getServiceType();
484         if (provider == null)
485             return null;
486
487         String JavaDoc serviceName = ts.getKey().getIdentifier();
488
489         Properties JavaDoc properties = provider.getServiceProperties(serviceName, (Properties JavaDoc) null);
490
491         properties = new UpdateServiceProperties(provider, serviceName, properties, true);
492
493         return setLocale(properties, userDefinedLocale);
494
495     }
496
497     /**
498         Set the locale for the service at boot time. The passed in
499         properties must be the one passed to the boot method.
500
501         @exception StandardException Standard Cloudscape error.
502     */

503     public Locale JavaDoc setLocale(Properties JavaDoc serviceProperties, String JavaDoc userDefinedLocale)
504         throws StandardException {
505
506         Locale JavaDoc locale = staticGetLocaleFromString(userDefinedLocale);
507
508         // this will write the property through to the service.properties file.
509
serviceProperties.put(Property.SERVICE_LOCALE, locale.toString());
510
511         return locale;
512     }
513
514     /**
515         Return the PersistentService object for a service.
516         Will return null if the service does not exist.
517     */

518     public PersistentService getServiceType(Object JavaDoc serviceModule) {
519         TopService ts = findTopService(serviceModule);
520
521         if (ts == null)
522             return null;
523
524         return ts.getServiceType();
525     }
526
527
528     /**
529         Start a module.
530
531         @exception StandardException se An attempt to start the module failed.
532
533         @see ModuleFactory#startModule
534     */

535     public Object JavaDoc startModule(boolean create, Object JavaDoc serviceModule, String JavaDoc factoryInterface,
536         String JavaDoc identifier, Properties JavaDoc properties) throws StandardException {
537
538
539         ProtocolKey key = ProtocolKey.create(factoryInterface, identifier);
540
541         TopService ts = findTopService(serviceModule);
542
543         Object JavaDoc instance = ts.bootModule(create, serviceModule, key, properties);
544
545         if (instance == null)
546             throw Monitor.missingImplementation(factoryInterface);
547
548         return instance;
549     }
550
551     private synchronized TopService findTopService(Object JavaDoc serviceModule) {
552
553         if (serviceModule == null)
554             return (TopService) services.elementAt(0);
555
556         for (int i = 1; i < services.size(); i++) {
557             TopService ts = (TopService) services.elementAt(i);
558             if (ts.inService(serviceModule))
559                 return ts;
560         }
561
562         return null;
563     }
564
565     public Object JavaDoc findModule(Object JavaDoc serviceModule, String JavaDoc factoryInterface, String JavaDoc identifier)
566     {
567
568         ProtocolKey key;
569
570         try {
571             key = ProtocolKey.create(factoryInterface, identifier);
572         } catch (StandardException se) {
573             return null;
574         }
575
576         TopService ts = findTopService(serviceModule);
577         if (ts == null)
578             return null;
579
580         return ts.findModule(key, true, null);
581     }
582
583
584     /**
585         Obtain a class that supports the given identifier.
586
587         @param fmtId identifer to associate with class
588
589         @return a reference InstanceGetter
590
591         @exception StandardException See Monitor.classFromIdentifier
592
593         @see ModuleFactory#classFromIdentifier
594     */

595     public InstanceGetter classFromIdentifier(int fmtId)
596         throws StandardException {
597
598         String JavaDoc className;
599         int off;
600         InstanceGetter[] iga;
601         InstanceGetter ig;
602
603         try {
604
605             off = fmtId - StoredFormatIds.MIN_TWO_BYTE_FORMAT_ID;
606             iga = rc2;
607             if (iga == null) {
608                 iga = rc2 = new InstanceGetter[RegisteredFormatIds.TwoByte.length];
609             }
610
611             ig = iga[off];
612             if (ig != null) {
613                 return ig;
614             }
615             className = RegisteredFormatIds.TwoByte[off];
616
617         } catch (ArrayIndexOutOfBoundsException JavaDoc aioobe) {
618             className = null;
619             iga = null;
620             off = 0;
621         }
622
623         if (className != null) {
624
625             Throwable JavaDoc t;
626             try {
627                 Class JavaDoc clazz = Class.forName(className);
628
629                 // See if it is a FormatableInstanceGetter
630
if (FormatableInstanceGetter.class.isAssignableFrom(clazz)) {
631                     FormatableInstanceGetter tfig = (FormatableInstanceGetter) clazz.newInstance();
632                     tfig.setFormatId(fmtId);
633                     return iga[off] = tfig;
634                 }
635
636                 return iga[off] = new ClassInfo(clazz);
637
638             } catch (ClassNotFoundException JavaDoc cnfe) {
639                 t = cnfe;
640             } catch (IllegalAccessException JavaDoc iae) {
641                 t = iae;
642             } catch (InstantiationException JavaDoc ie) {
643                 t = ie;
644             } catch (LinkageError JavaDoc le) {
645                 t = le;
646             }
647             throw StandardException.newException(SQLState.REGISTERED_CLASS_LINAKGE_ERROR,
648                 t, FormatIdUtil.formatIdToString(fmtId), className);
649         }
650
651         throw StandardException.newException(SQLState.REGISTERED_CLASS_NONE, FormatIdUtil.formatIdToString(fmtId));
652     }
653
654
655     /**
656         Obtain an new instance of a class that supports the given identifier.
657
658         @return a reference to a newly created object or null if a matching class
659                 cannot be found.
660     */

661     public Object JavaDoc newInstanceFromIdentifier(int identifier)
662         throws StandardException {
663
664         InstanceGetter ci = classFromIdentifier(identifier);
665
666         Throwable JavaDoc t;
667         try {
668             Object JavaDoc result = ci.getNewInstance();
669 /*
670                 if (SanityManager.DEBUG) {
671                     if(SanityManager.DEBUG_ON(Monitor.NEW_INSTANCE_FROM_ID_TRACE_DEBUG_FLAG))
672                     {
673                         String traceResult = "null";
674
675                         if (result != null) traceResult = "not null";
676
677                         SanityManager.DEBUG(Monitor.NEW_INSTANCE_FROM_ID_TRACE_DEBUG_FLAG,
678                                             "newInstanceFromIdentifier("+identifier+") "+
679                                             " ClassName: "+
680                                             result.getClass().getName() +
681                                             " returned "+
682                                             traceResult);
683                     }
684                 }
685 */

686             return result;
687         }
688         catch (InstantiationException JavaDoc ie) {
689             t = ie;
690         }
691         catch (IllegalAccessException JavaDoc iae) {
692             t = iae;
693         }
694         catch (InvocationTargetException JavaDoc ite) {
695             t = ite;
696         }
697         catch (LinkageError JavaDoc le) {
698             t = le;
699         }
700         throw StandardException.newException(SQLState.REGISTERED_CLASS_INSTANCE_ERROR,
701             t, new Integer JavaDoc(identifier), "XX" /*ci.getClassName()*/);
702     }
703
704     private Boolean JavaDoc exceptionTrace;
705
706     /**
707         load a module instance.
708
709         Look through the implementations for a module that implements the
710         required factory interface and can handle the properties given.
711
712         The module's start or create method is not called.
713     */

714
715     protected Object JavaDoc loadInstance(Class JavaDoc factoryInterface, Properties JavaDoc properties) {
716
717         Object JavaDoc instance = null;
718
719         Vector JavaDoc localImplementations = getImplementations(properties, false);
720         if (localImplementations != null) {
721             instance = loadInstance(localImplementations, factoryInterface, properties);
722         }
723
724         for (int i = 0; i < implementationSets.length; i++) {
725             instance = loadInstance(implementationSets[i], factoryInterface, properties);
726             if (instance != null)
727                 break;
728         }
729
730         return instance;
731     }
732
733
734     private Object JavaDoc loadInstance(Vector JavaDoc implementations, Class JavaDoc factoryInterface, Properties JavaDoc properties) {
735
736         for (int index = 0; true; index++) {
737
738             // find an implementation
739
index = findImplementation(implementations, index, factoryInterface);
740             if (index < 0)
741                 return null;
742
743             // try to create an instance
744
Object JavaDoc instance = newInstance((Class JavaDoc) implementations.elementAt(index));
745
746             if (BaseMonitor.canSupport(instance, properties))
747                 return instance;
748         }
749     }
750
751
752     /**
753         Find a class that implements the required index, return the index
754         into the implementations vecotr of that class. Returns -1 if no class
755         could be found.
756     */

757     private static int findImplementation(Vector JavaDoc implementations, int startIndex, Class JavaDoc factoryInterface) {
758
759         for (int i = startIndex; i < implementations.size(); i++) {
760
761             //try {
762
Class JavaDoc factoryClass = (Class JavaDoc) implementations.elementAt(i);
763                 if (!factoryInterface.isAssignableFrom(factoryClass)) {
764                     continue;
765                 }
766
767                 return i;
768             //}
769
//catch (ClassNotFoundException e) {
770
// report("Class not found " + (String) implementations.elementAt(i));
771
// continue;
772
//}
773
}
774
775         return -1;
776     }
777
778     /**
779     */

780     private Object JavaDoc newInstance(String JavaDoc className) {
781
782         try {
783
784             Class JavaDoc factoryClass = Class.forName(className);
785             return factoryClass.newInstance();
786         }
787         catch (ClassNotFoundException JavaDoc e) {
788             report(className + " " + e.toString());
789         }
790         catch (InstantiationException JavaDoc e) {
791             report(className + " " + e.toString());
792         }
793         catch (IllegalAccessException JavaDoc e) {
794             report(className + " " + e.toString());
795         }
796         catch (LinkageError JavaDoc le) {
797             report(className + " " + le.toString());
798             reportException(le);
799         }
800
801         return null;
802     }
803     /**
804     */

805     private Object JavaDoc newInstance(Class JavaDoc classObject) {
806
807         try {
808             return classObject.newInstance();
809         }
810         catch (InstantiationException JavaDoc e) {
811             report(classObject.getName() + " " + e.toString());
812         }
813         catch (IllegalAccessException JavaDoc e) {
814             report(classObject.getName() + " " + e.toString());
815         }
816         catch (LinkageError JavaDoc le) {
817             report(classObject.getName() + " " + le.toString());
818             reportException(le);
819         }
820
821         return null;
822     }
823
824     public Properties JavaDoc getApplicationProperties() {
825         return applicationProperties;
826     }
827
828     /**
829         Return an array of the service identifiers that are running and
830         implement the passed in protocol (java interface class name).
831
832         @return The list of service names, if no services exist that
833         implement the protocol an array with zero elements is returned.
834
835         @see ModuleFactory#getServiceList
836     */

837     public String JavaDoc[] getServiceList(String JavaDoc protocol) {
838
839         TopService ts;
840
841         synchronized (this) {
842             int count = 0;
843
844             // count the number of services that implement the required protocol
845
for (int i = 1; i < services.size(); i++) {
846                 ts = (TopService) services.elementAt(i);
847                 if (ts.isActiveService()) {
848                     if (ts.getKey().getFactoryInterface().getName().equals(protocol))
849                         count++;
850                 }
851             }
852
853             // and then fill in the newly allocated string array
854
String JavaDoc[] list = new String JavaDoc[count];
855             if (count != 0) {
856                 int j = 0;
857                 for (int i = 1; i < services.size(); i++) {
858                     ts = (TopService) services.elementAt(i);
859                     if (ts.isActiveService()) {
860                         if (ts.getKey().getFactoryInterface().getName().equals(protocol)) {
861                             list[j++] = ts.getServiceType().getUserServiceName(ts.getKey().getIdentifier());
862                             if (j == count)
863                                 break;
864                         }
865                     }
866                 }
867             }
868             return list;
869         }
870     }
871
872     /*
873     ** non-public methods.
874     */

875
876
877     void dumpProperties(String JavaDoc title, Properties JavaDoc props) {
878         if (SanityManager.DEBUG) {
879             // this method is only called if reportOn is true, so no need to check it here
880
report(title);
881             if (props != null) {
882                 for (Enumeration JavaDoc e = props.propertyNames(); e.hasMoreElements(); ) {
883                     String JavaDoc key = (String JavaDoc) e.nextElement();
884                     // Get property as object in case of non-string properties
885
report(key + "=" + props.getProperty(key));
886                 }
887             }
888             report("-- end --");
889         }
890
891     }
892
893
894     /**
895         Should only be called if reportOn is true
896         apart from report/Exception().
897     */

898     protected void report(String JavaDoc message) {
899
900         PrintWriter JavaDoc tpw = getTempWriter();
901
902         if (tpw != null)
903             tpw.println(message);
904
905         if (systemStreams != null)
906             systemStreams.stream().printlnWithHeader(message);
907     }
908
909     protected void reportException(Throwable JavaDoc t) {
910
911
912         PrintWriterGetHeader pwgh = null;
913         if (systemStreams != null)
914             pwgh = systemStreams.stream().getHeader();
915
916         ErrorStringBuilder esb = new ErrorStringBuilder(pwgh);
917
918         esb.appendln(t.getMessage());
919         esb.stackTrace(t);
920
921         report(esb.get().toString());
922     }
923
924     private void addDebugFlags(String JavaDoc flags, boolean set) {
925         if (SanityManager.DEBUG) {
926             if (flags == null)
927                 return;
928
929             StringTokenizer JavaDoc st = new StringTokenizer JavaDoc(flags, ",");
930             for (; st.hasMoreTokens(); ) {
931                 String JavaDoc flag = st.nextToken();
932
933                 if (set)
934                     SanityManager.DEBUG_SET(flag);
935                 else
936                     SanityManager.DEBUG_CLEAR(flag);
937             }
938         }
939     }
940
941     /**
942         Look for any services in the a properties set and the application
943         property set and then start them.
944
945         A service is defined by derby.service.name=protocol
946     */

947     private static final String JavaDoc SERVICE = "derby.service.";
948
949     public void startServices(Properties JavaDoc properties, boolean bootAll) {
950
951         if (properties == null)
952             return;
953
954         for (Enumeration JavaDoc e = properties.propertyNames(); e.hasMoreElements(); ) {
955
956             String JavaDoc key = (String JavaDoc) e.nextElement();
957             if (key.startsWith(SERVICE)) {
958                 String JavaDoc name = key.substring(SERVICE.length());
959
960                 String JavaDoc protocolOrType = properties.getProperty(key);
961
962                 try {
963                     if (protocolOrType.equals(Monitor.SERVICE_TYPE_DIRECTORY)) {
964                         if (bootAll) // only if automatic booting is required
965
findProviderAndStartService(name, properties, true);
966                     } else {
967                         bootService((PersistentService) null,
968                             protocolOrType, name, (Properties JavaDoc)null, false);
969                     }
970
971                 } catch (StandardException se) {
972                     // error already in error log, just continue booting
973
// for persistent services, but non-persistent ones
974
// will not have put the error in the log
975
if (!protocolOrType.equals(Monitor.SERVICE_TYPE_DIRECTORY))
976                         reportException(se);
977                 }
978             }
979         }
980     }
981
982     /**
983         Start a peristent service.
984
985         @see ModuleFactory#startPersistentService
986         @see Monitor#startPersistentService
987     */

988     public final boolean startPersistentService(String JavaDoc name, Properties JavaDoc properties)
989         throws StandardException {
990
991         return findProviderAndStartService(name, properties, false);
992
993     }
994
995     /**
996         Create a persistent service.
997
998         @return The module from the service if it was created successfully, null if a service already existed.
999
1000        @exception StandardException An exception was thrown trying to create the service.
1001
1002        @see Monitor#createPersistentService
1003    */

1004
1005    public Object JavaDoc createPersistentService(String JavaDoc factoryInterface, String JavaDoc name, Properties JavaDoc properties)
1006        throws StandardException {
1007
1008
1009        PersistentService provider = findProviderForCreate(name);
1010        if (provider == null) {
1011            throw StandardException.newException(SQLState.PROTOCOL_UNKNOWN, name);
1012        }
1013
1014        return bootService(provider, factoryInterface, name, properties, true);
1015    }
1016    /**
1017     * Removes a PersistentService.
1018     * Could be used for drop database.
1019       @param name : Service name to be removed.
1020       
1021    */

1022    public void removePersistentService(String JavaDoc name)
1023         throws StandardException
1024    {
1025        PersistentService provider=null;
1026        provider = findProviderForCreate(name);
1027        String JavaDoc serviceName = provider.getCanonicalServiceName(name);
1028        boolean removed = provider.removeServiceRoot(serviceName);
1029        if (removed == false)
1030            throw StandardException.newException(SQLState.SERVICE_DIRECTORY_REMOVE_ERROR,serviceName);
1031    }
1032    /**
1033        Start a non-persistent service.
1034
1035        @see Monitor#startNonPersistentService
1036        @see ModuleFactory#startNonPersistentService
1037    */

1038    public Object JavaDoc startNonPersistentService(String JavaDoc factoryInterface, String JavaDoc serviceName, Properties JavaDoc properties)
1039        throws StandardException {
1040
1041        return bootService((PersistentService) null, factoryInterface, serviceName, properties, false);
1042    }
1043
1044
1045    /**
1046        Create an implementation set.
1047        Look through the properties object for all properties that
1048        start with derby.module and add the value into the vector.
1049
1050        If no implementations are listed in the properties object
1051        then null is returned.
1052    */

1053    private Vector JavaDoc getImplementations(Properties JavaDoc moduleList, boolean actualModuleList) {
1054
1055        if (moduleList == null)
1056            return null;
1057
1058        Vector JavaDoc implementations = actualModuleList ? new Vector JavaDoc(moduleList.size()) : new Vector JavaDoc(0,1);
1059
1060        // Get my current JDK environment
1061
int theJDKId = JVMInfo.JDK_ID;
1062
1063        int[] envModuleCount = new int[theJDKId + 1];
1064
1065nextModule:
1066        for (Enumeration JavaDoc e = moduleList.propertyNames(); e.hasMoreElements(); ) {
1067
1068            String JavaDoc key = (String JavaDoc) e.nextElement();
1069            
1070            // module tagged name in the modules.properties file.
1071
// used as the tag for dependent properties.
1072
String JavaDoc tag;
1073            
1074            // Dynamically loaded code is defined by a property of
1075
// the form:
1076
// derby.module.<modulename>=<class name>
1077
// or
1078
// derby.subSubProtocol.<modulename>=<classname>
1079

1080            if (key.startsWith(Property.MODULE_PREFIX)) {
1081                tag = key.substring(Property.MODULE_PREFIX.length());
1082            } else if (key.startsWith(Property.SUB_SUB_PROTOCOL_PREFIX)) {
1083                tag = key.substring(Property.MODULE_PREFIX.length());
1084            } else {
1085                continue nextModule;
1086            }
1087            
1088
1089            // Check to see if it has any environment requirements
1090

1091            // derby.env.jdk.<modulename> - Any JDK requirements.
1092
String JavaDoc envKey = Property.MODULE_ENV_JDK_PREFIX.concat(tag);
1093            String JavaDoc envJDK = moduleList.getProperty(envKey);
1094            int envJDKId = 0;
1095            
1096            if (envJDK != null) {
1097                envJDKId = Integer.parseInt(envJDK.trim());
1098                if (envJDKId > theJDKId) {
1099                    continue nextModule;
1100                }
1101            }
1102
1103            // derby.env.classes.<tag> - Any class requirements
1104
envKey = Property.MODULE_ENV_CLASSES_PREFIX.concat(tag);
1105            String JavaDoc envClasses = moduleList.getProperty(envKey);
1106            if (envClasses != null) {
1107
1108                StringTokenizer JavaDoc st = new StringTokenizer JavaDoc(envClasses, ",");
1109                for (; st.hasMoreTokens(); ) {
1110                    try {
1111                        Class.forName(st.nextToken().trim());
1112                    } catch (ClassNotFoundException JavaDoc cnfe) {
1113                        continue nextModule;
1114                    } catch (LinkageError JavaDoc le) {
1115                        continue nextModule;
1116                    }
1117                }
1118            }
1119
1120
1121
1122            // Try to load the class
1123
// if we can't load the class or create an instance then
1124
// we don't use this calls as a valid module implementation
1125
String JavaDoc className = moduleList.getProperty(key);
1126
1127            if (SanityManager.DEBUG && reportOn) {
1128                report("Accessing module " + className + " to run initializers at boot time");
1129            }
1130
1131            try {
1132                Class JavaDoc possibleModule = Class.forName(className);
1133
1134                // Look for the monitors special modules, PersistentService ones.
1135
if (getPersistentServiceImplementation(possibleModule))
1136                    continue;
1137                
1138                
1139                if( StorageFactory.class.isAssignableFrom(possibleModule)) {
1140                    storageFactories.put(tag, className);
1141                    continue;
1142                }
1143
1144
1145                // If this is a specific JDK version (environment) module
1146
// then it must be ordered in the implementation list by envJDKId.
1147
// Those with a higher number are at the front, e.g.
1148
//
1149
// JDK 1.4 modules (envJDKId == 4)
1150
// JDK 1.2/1.3 modules (envJDKId == 2)
1151
// JDK 1.1 modules (envJDKId == 1)
1152
// generic modules (envJDKId == 0 (not set in modules.properties)
1153
//
1154
// Note modules with envJDKId > theJDKId do not get here
1155

1156                if (envJDKId != 0) {
1157
1158                    // total how many modules with a higher envJDKId are ahead of us
1159
int offset = 0;
1160                    for (int eji = theJDKId; eji > envJDKId; eji--) {
1161                        offset += envModuleCount[eji];
1162                    }
1163
1164                    implementations.insertElementAt(possibleModule, offset);
1165                    envModuleCount[envJDKId]++;
1166
1167                }
1168                else {
1169                    // just add to the end of the vector
1170
implementations.addElement(possibleModule);
1171                }
1172
1173                // Since ModuleControl and ModuleSupportable are not called directly
1174
// check that if the have the methods then the class implements the
1175
// interface.
1176
if (SanityManager.DEBUG) {
1177                    // ModuleSupportable
1178
Class JavaDoc[] csParams = { new java.util.Properties JavaDoc().getClass()};
1179                    try {
1180                        possibleModule.getMethod("canSupport", csParams);
1181                        if (!ModuleSupportable.class.isAssignableFrom(possibleModule)) {
1182                            SanityManager.THROWASSERT("Module does not implement ModuleSupportable but has canSupport() - " + className);
1183                        }
1184                    } catch (NoSuchMethodException JavaDoc nsme){/* ok*/}
1185
1186                    // ModuleControl
1187
boolean eitherMethod = false;
1188
1189                    Class JavaDoc[] bootParams = {Boolean.TYPE, new java.util.Properties JavaDoc().getClass()};
1190                    try {
1191                        possibleModule.getMethod("boot", bootParams);
1192                        eitherMethod = true;
1193                    } catch (NoSuchMethodException JavaDoc nsme){/*ok*/}
1194
1195                    Class JavaDoc[] stopParams = {};
1196                    try {
1197                        possibleModule.getMethod("stop", stopParams);
1198                        eitherMethod = true;
1199                    } catch (NoSuchMethodException JavaDoc nsme){/*ok*/}
1200
1201                    if (eitherMethod) {
1202                        if (!ModuleControl.class.isAssignableFrom(possibleModule)) {
1203                            SanityManager.THROWASSERT("Module does not implement ModuleControl but has its methods - " + className);
1204                        }
1205                    }
1206                }
1207
1208            }
1209            catch (ClassNotFoundException JavaDoc cnfe) {
1210                report("Class " + className + " " + cnfe.toString() + ", module ignored.");
1211            }
1212            catch (LinkageError JavaDoc le) {
1213                report("Class " + className + " " + le.toString() + ", module ignored.");
1214            }
1215        }
1216        
1217        if (implementations.isEmpty())
1218            return null;
1219        implementations.trimToSize();
1220
1221        return implementations;
1222    }
1223
1224    private boolean getPersistentServiceImplementation( Class JavaDoc possibleModule)
1225    {
1226        if( ! PersistentService.class.isAssignableFrom(possibleModule))
1227            return false;
1228
1229        PersistentService ps = (PersistentService) newInstance(possibleModule);
1230        if (ps == null) {
1231            report("Class " + possibleModule.getName() + " cannot create instance, module ignored.");
1232        } else {
1233            if (serviceProviders == null)
1234                serviceProviders = new Hashtable JavaDoc(3, (float) 1.0);
1235            serviceProviders.put(ps.getType(), ps);
1236        }
1237        return true;
1238    } // end of getPersistentServiceImplementation
1239

1240    private Vector JavaDoc getDefaultImplementations() {
1241
1242        Properties JavaDoc moduleList = getDefaultModuleProperties();
1243
1244        return getImplementations(moduleList, true);
1245    } // end of getDefaultImplementations
1246

1247    /**
1248     * Get the complete set of module properties by
1249     * loading in contents of all the org/apache/derby/modules.properties
1250     * files. This must be executed in a privileged block otherwise
1251     * when running in a security manager environment no properties will
1252     * be returned.
1253     */

1254    Properties JavaDoc getDefaultModuleProperties()
1255    {
1256        // SECURITY PERMISSION - IP1 for modules in this jar
1257
// or other jars shipped with the Derby release.
1258
Properties JavaDoc moduleList = new Properties JavaDoc();
1259        boolean firstList = true;
1260
1261        ClassLoader JavaDoc cl = getClass().getClassLoader();
1262        try {
1263            Enumeration JavaDoc e = cl == null ?
1264                ClassLoader.getSystemResources("org/apache/derby/modules.properties") :
1265                cl.getResources("org/apache/derby/modules.properties");
1266            while (e.hasMoreElements()) {
1267                URL JavaDoc modulesPropertiesURL = (URL JavaDoc) e.nextElement();
1268                InputStream JavaDoc is = null;
1269                try {
1270                    is = modulesPropertiesURL.openStream();
1271                    if( firstList) {
1272                        moduleList.load( is);
1273                        firstList = false;
1274                    }
1275                    else {
1276                        // Check for duplicates
1277
Properties JavaDoc otherList = new Properties JavaDoc();
1278                        otherList.load( is);
1279                        for( Enumeration JavaDoc newKeys = otherList.keys(); newKeys.hasMoreElements() ;)
1280                        {
1281                            String JavaDoc key = (String JavaDoc) newKeys.nextElement();
1282                            if( moduleList.contains( key))
1283                                // RESOLVE how do we localize messages before we have finished initialization?
1284
report( "Ignored duplicate property " + key + " in " + modulesPropertiesURL.toString());
1285                            else
1286                                moduleList.setProperty( key, otherList.getProperty( key));
1287                        }
1288                    }
1289                } catch (IOException JavaDoc ioe) {
1290                    if (SanityManager.DEBUG)
1291                        report("Can't load implementation list " + modulesPropertiesURL.toString() + ": " + ioe.toString());
1292                } finally {
1293                    try {
1294                        if( is != null)
1295                            is.close();
1296                    } catch (IOException JavaDoc ioe2) {
1297                    }
1298                }
1299            }
1300        } catch (IOException JavaDoc ioe) {
1301            if (SanityManager.DEBUG)
1302                report("Can't load implementation list: " + ioe.toString());
1303        }
1304        if (SanityManager.DEBUG)
1305        {
1306            if (firstList)
1307                report("Default implementation list not found");
1308        }
1309 
1310        return moduleList;
1311    }
1312
1313    /*
1314    ** Class methods
1315    */

1316
1317    /**
1318        Return a property set that has the runtime properties removed.
1319    */

1320    protected static Properties JavaDoc removeRuntimeProperties(Properties JavaDoc properties) {
1321
1322        Properties JavaDoc subset = new Properties JavaDoc();
1323
1324        for (Enumeration JavaDoc e = properties.keys(); e.hasMoreElements(); ) {
1325
1326            String JavaDoc key = (String JavaDoc) e.nextElement();
1327            if (key.startsWith(Property.PROPERTY_RUNTIME_PREFIX))
1328                continue;
1329
1330            subset.put(key, properties.get(key));
1331        }
1332
1333        return subset;
1334    }
1335
1336
1337    /**
1338        Get InputStream for application properties file Returns nul if it does not exist.
1339    */

1340    abstract InputStream JavaDoc applicationPropertiesStream()
1341      throws IOException JavaDoc;
1342
1343
1344    /**
1345    */

1346    protected Properties JavaDoc readApplicationProperties() {
1347
1348        InputStream JavaDoc is = null;
1349
1350        try {
1351            // SECURITY PERMISSION - OP3
1352
is = applicationPropertiesStream();
1353            if (is == null)
1354                return null;
1355
1356            Properties JavaDoc properties = new Properties JavaDoc();
1357
1358            // Trim off excess whitespace from properties file, if any,
1359
// and then load the properties into 'properties'.
1360
org.apache.derby.iapi.util.PropertyUtil.loadWithTrimmedValues(
1361                new BufferedInputStream JavaDoc(is), properties);
1362
1363            return properties;
1364
1365        } catch (SecurityException JavaDoc se) {
1366            return null;
1367        } catch (IOException JavaDoc ioe) {
1368            report(ioe.toString() + " (" + Property.PROPERTIES_FILE + ")");
1369            reportException(ioe);
1370            return null;
1371
1372        }finally {
1373
1374
1375            try {
1376                if (is != null) {
1377                    is.close();
1378                    is = null;
1379                }
1380
1381            } catch (IOException JavaDoc e) {
1382            }
1383        }
1384    }
1385
1386
1387    /*
1388    ** Methods related to service providers.
1389    **
1390    ** A service provider implements PersistentService and
1391    ** abstracts out:
1392    **
1393    ** Finding all serivces that should be started at boot time.
1394    ** Finding the service.properties file for a service
1395    ** Creating a service's root.
1396    **
1397    ** A monitor can have any number of service providers installed,
1398    ** any module that implements PersistentService is treated specially
1399    ** and stored only in the serviceProviders hashtable, indexed by
1400    ** its getType() method.
1401    **
1402    ** Once all the implementations have loaded the service providers
1403    ** are booted. If they fail to boot then they aare discarded.
1404    ** E.g. a marimba service provider may detect that its not in
1405    ** a channel so it refuses to boot.
1406    */

1407
1408    /**
1409        Boot all the service providers, ie. any module that implemented
1410        PersistentService. Upon entry to this call is the hashtable has
1411        PersistentService objects that have been created but not booted.
1412    */

1413    protected void bootServiceProviders() {
1414
1415        if (serviceProviders == null) {
1416            return;
1417        }
1418
1419        for (Enumeration JavaDoc e = serviceProviders.keys(); e.hasMoreElements(); ) {
1420
1421            String JavaDoc serviceType = (String JavaDoc) e.nextElement();
1422            Object JavaDoc provider = serviceProviders.get(serviceType);
1423
1424            // see if this provider can live in this environment
1425
if (!BaseMonitor.canSupport(provider, (Properties JavaDoc) null)) {
1426                serviceProviders.remove(serviceType);
1427                continue;
1428            }
1429        }
1430    }
1431    /**
1432        Boot all persistent services that can be located at run time.
1433
1434        <BR>
1435        This method enumerates through all the service providers that
1436        are active and calls bootPersistentServices(PersistentService)
1437        to boot all the services that that provider knows about.
1438    */

1439    protected void bootPersistentServices() {
1440        Enumeration JavaDoc e = new ProviderEnumeration( applicationProperties);
1441        while (e.hasMoreElements()) {
1442            PersistentService provider = (PersistentService) e.nextElement();
1443            bootProviderServices(provider);
1444        }
1445
1446    }
1447
1448    /**
1449        Boot all persistent services that can be located by a single service provider
1450
1451        <BR>
1452        This method enumerates through all the service providers that
1453        are active and calls bootPersistentServices(PersistentService)
1454        to boot all the services that that provider knows about.
1455    */

1456    protected void bootProviderServices(PersistentService provider) {
1457
1458        if (SanityManager.DEBUG && reportOn) {
1459            report("Booting persistent services for provider: " + provider.getType());
1460        }
1461
1462        for (Enumeration JavaDoc e = provider.getBootTimeServices(); (e != null) && e.hasMoreElements(); ) {
1463
1464            String JavaDoc serviceName = (String JavaDoc) e.nextElement();
1465
1466            Properties JavaDoc serviceProperties;
1467            try {
1468                serviceProperties = provider.getServiceProperties(serviceName, null);
1469            } catch (StandardException mse) {
1470                report("Failed to load service properties, name: " + serviceName + ", type = " + provider.getType());
1471                reportException(mse);
1472                continue;
1473            }
1474
1475            // see if this service does not want to be auto-booted.
1476
if (Boolean.valueOf(serviceProperties.getProperty(Property.NO_AUTO_BOOT)).booleanValue())
1477                continue;
1478
1479
1480            try {
1481                startProviderService(provider, serviceName, serviceProperties);
1482            } catch (StandardException mse) {
1483                report("Service failed to boot, name: " + serviceName + ", type = " + provider.getType());
1484                reportException(mse);
1485                continue;
1486            }
1487        }
1488    }
1489    /**
1490        Find a provider and start a service.
1491    */

1492    private boolean findProviderAndStartService(String JavaDoc name,
1493                          Properties JavaDoc properties, boolean bootTime)
1494        throws StandardException {
1495
1496        PersistentService actualProvider = null;
1497
1498        Properties JavaDoc serviceProperties = null;
1499        String JavaDoc serviceName = null;
1500
1501        // see if the name already includes a service type
1502
int colon = name.indexOf(':');
1503        if (colon != -1) {
1504            actualProvider = findProviderFromName(name, colon);
1505
1506            // if null is returned here then its a sub-sub protocol/provider
1507
// that we don't understand. Attempt to load it as an untyped name.
1508
// If we have a protool
1509
// that we do understand and we can't open the service we will
1510
// throw an exception
1511
if (actualProvider != null) {
1512
1513                serviceName = actualProvider.getCanonicalServiceName(name);
1514                if (serviceName == null)
1515                    return true; // we understand the type, but the service does not exist
1516

1517                serviceProperties =
1518                    actualProvider.getServiceProperties(serviceName, properties);
1519
1520                if (serviceProperties == null)
1521                    return true; // we understand the type, but the service does not exist
1522

1523                // see if this service does not want to be auto-booted.
1524
if (bootTime && Boolean.valueOf(serviceProperties.getProperty(Property.NO_AUTO_BOOT)).booleanValue())
1525                    return true;
1526
1527                startProviderService(actualProvider, serviceName, serviceProperties);
1528                return true; // we understand the type
1529
}
1530        }
1531
1532        StandardException savedMse = null;
1533
1534        for (Enumeration JavaDoc e = new ProviderEnumeration( properties); e.hasMoreElements(); ) {
1535
1536            PersistentService provider = (PersistentService) e.nextElement();
1537
1538            String JavaDoc sn = provider.getCanonicalServiceName(name);
1539            if (sn == null)
1540                continue;
1541
1542            Properties JavaDoc p = null;
1543            try {
1544                p = provider.getServiceProperties(sn, properties);
1545                // service does not exist.
1546
if (p == null)
1547                    continue;
1548
1549            } catch (StandardException mse) {
1550                savedMse = mse;
1551            }
1552
1553
1554            // yes we can attempt to boot this service
1555
if (actualProvider == null) {
1556                actualProvider = provider;
1557                serviceName = sn;
1558                serviceProperties = p;
1559                continue;
1560            }
1561
1562            // we have an ambigious service name
1563
throw StandardException.newException(SQLState.AMBIGIOUS_PROTOCOL, name);
1564        }
1565
1566        // no such service, if this was a name with no type, ie just name instead of type:name.
1567
// the monitor claims to always understand these.
1568
if (actualProvider == null)
1569            return colon == -1;
1570
1571        if (savedMse != null)
1572            throw savedMse;
1573
1574        // see if this service does not want to be auto-booted.
1575
if (bootTime && Boolean.valueOf(serviceProperties.getProperty(Property.NO_AUTO_BOOT)).booleanValue())
1576            return true;
1577
1578        startProviderService(actualProvider, serviceName, serviceProperties);
1579        return true;
1580    }
1581
1582    protected PersistentService findProviderForCreate(String JavaDoc name) throws StandardException {
1583        // RESOLVE - hard code creating databases in directories for now.
1584
return (PersistentService) findProviderFromName(name, name.indexOf(':'));
1585    }
1586
1587    /**
1588        Find the service provider from a name that includes a service type,
1589        ie. is of the form 'type:name'. If type is less than 3 characters
1590        then it is assumed to be of type directory, i.e. a windows driver letter.
1591    */

1592    private PersistentService findProviderFromName(String JavaDoc name, int colon) throws StandardException
1593    {
1594        // empty type, treat as a unknown protocol
1595
if (colon == 0)
1596            return null;
1597
1598        String JavaDoc serviceType;
1599        if (colon < 2) {
1600            // assume it's a windows path (a:/foo etc.) and set the type to be DIRECTORY
1601
serviceType = PersistentService.DIRECTORY;
1602        } else {
1603            serviceType = name.substring(0, colon);
1604        }
1605        return getServiceProvider(serviceType);
1606    }
1607
1608    public PersistentService getServiceProvider(String JavaDoc subSubProtocol) throws StandardException
1609    {
1610        if( subSubProtocol == null)
1611            return null;
1612        if( serviceProviders != null)
1613        {
1614            PersistentService ps = (PersistentService) serviceProviders.get( subSubProtocol);
1615            if( ps != null)
1616                return ps;
1617        }
1618        return getPersistentService(subSubProtocol);
1619    } // end of getServiceProvider
1620

1621 
1622    /**
1623     * Return a PersistentService implementation to handle the subSubProtocol.
1624     * @return Valid PersistentService or null if the protocol is not handled.
1625      */

1626    private PersistentService getPersistentService(String JavaDoc subSubProtocol)
1627        throws StandardException
1628    {
1629        String JavaDoc className = getStorageFactoryClassName(subSubProtocol);
1630        return getPersistentService( className, subSubProtocol);
1631    }
1632
1633    private PersistentService getPersistentService( final String JavaDoc className, String JavaDoc subSubProtocol) throws StandardException
1634    {
1635        if( className == null)
1636            return null;
1637        Class JavaDoc storageFactoryClass = null;
1638        try
1639        {
1640            storageFactoryClass = Class.forName( className);
1641       }
1642        catch (Throwable JavaDoc e)
1643        {
1644            throw StandardException.newException( SQLState.INSTANTIATE_STORAGE_FACTORY_ERROR,
1645                                                  e,
1646                                                  subSubProtocol, className);
1647        }
1648        return new StorageFactoryService( subSubProtocol, storageFactoryClass);
1649    } // end of getPersistentService
1650

1651    /**
1652     * Find the StorageFactory class name that handles the subSub protocol.
1653     * Looks in the system property set and the set defined during boot.
1654 
1655      * @return Valid class name, or null if no StorageFactory handles the protocol.
1656     */

1657    private String JavaDoc getStorageFactoryClassName(String JavaDoc subSubProtocol)
1658    {
1659        String JavaDoc propertyName = Property.SUB_SUB_PROTOCOL_PREFIX + subSubProtocol;
1660        String JavaDoc className = PropertyUtil.getSystemProperty( propertyName);
1661        if( className != null)
1662            return className;
1663        return (String JavaDoc) storageFactories.get( subSubProtocol);
1664    } // end of getStorageFactoryClassName
1665

1666    private static final HashMap JavaDoc storageFactories = new HashMap JavaDoc();
1667    static {
1668        String JavaDoc dirStorageFactoryClass;
1669        if( JVMInfo.JDK_ID >= JVMInfo.J2SE_14)
1670            dirStorageFactoryClass = "org.apache.derby.impl.io.DirStorageFactory4";
1671        else
1672            dirStorageFactoryClass = "org.apache.derby.impl.io.DirStorageFactory";
1673
1674
1675        storageFactories.put( PersistentService.DIRECTORY, dirStorageFactoryClass);
1676        storageFactories.put( PersistentService.CLASSPATH,
1677                                "org.apache.derby.impl.io.CPStorageFactory");
1678        storageFactories.put( PersistentService.JAR,
1679                                "org.apache.derby.impl.io.JarStorageFactory");
1680        storageFactories.put( PersistentService.HTTP,
1681                                "org.apache.derby.impl.io.URLStorageFactory");
1682        storageFactories.put( PersistentService.HTTPS,
1683                                "org.apache.derby.impl.io.URLStorageFactory");
1684    }
1685
1686    /**
1687        Boot a service under the control of the provider
1688    */

1689    protected void startProviderService(PersistentService provider, String JavaDoc serviceName, Properties JavaDoc serviceProperties)
1690        throws StandardException {
1691
1692        String JavaDoc protocol = serviceProperties.getProperty(Property.SERVICE_PROTOCOL);
1693
1694        if (protocol == null) {
1695            throw StandardException.newException(SQLState.PROPERTY_MISSING, Property.SERVICE_PROTOCOL);
1696        }
1697
1698        bootService(provider, protocol, serviceName, serviceProperties, false);
1699    }
1700
1701    /**
1702        Boot (start or create) a service (persistent or non-persistent).
1703    */

1704    protected Object JavaDoc bootService(PersistentService provider,
1705        String JavaDoc factoryInterface, String JavaDoc serviceName, Properties JavaDoc properties,
1706        boolean create) throws StandardException {
1707
1708        //reget the canonical service name in case if it was recreated
1709
//after we got service name.(like in case of restoring from backup).
1710
if(provider != null)
1711            serviceName = provider.getCanonicalServiceName(serviceName);
1712        ProtocolKey serviceKey = ProtocolKey.create(factoryInterface, serviceName);
1713        if (SanityManager.DEBUG && reportOn) {
1714            report("Booting service " + serviceKey + " create = " + create);
1715        }
1716
1717        ContextManager previousCM = contextService.getCurrentContextManager();
1718        ContextManager cm = previousCM;
1719        Object JavaDoc instance;
1720        TopService ts = null;
1721        Context sb = null;
1722
1723
1724        try {
1725
1726
1727            synchronized (this) {
1728
1729                if (inShutdown) {
1730                    throw StandardException.newException(SQLState.CLOUDSCAPE_SYSTEM_SHUTDOWN);
1731                }
1732
1733                for (int i = 1; i < services.size(); i++) {
1734                    TopService ts2 = (TopService) services.elementAt(i);
1735                    if (ts2.isPotentialService(serviceKey)) {
1736                        // if the service already exists then just return null
1737
return null;
1738                    }
1739                }
1740
1741
1742                Locale JavaDoc serviceLocale = null;
1743                if (create) {
1744
1745                    
1746                    // always wrap the property set in an outer set.
1747
// this ensures that any random attributes from
1748
// a JDBC URL are not written into the service.properties
1749
// file (e.g. like user and password :-)
1750
properties = new Properties JavaDoc(properties);
1751
1752                    serviceLocale = setLocale(properties);
1753
1754                    properties.put(Property.SERVICE_PROTOCOL, factoryInterface);
1755
1756                    serviceName = provider.createServiceRoot(serviceName,
1757                            Boolean.valueOf(properties.getProperty(Property.DELETE_ON_CREATE)).booleanValue());
1758
1759                    serviceKey = ProtocolKey.create(factoryInterface, serviceName);
1760                } else if (properties != null) {
1761                    String JavaDoc serverLocaleDescription = properties.getProperty(Property.SERVICE_LOCALE);
1762                    if ( serverLocaleDescription != null)
1763                        serviceLocale = staticGetLocaleFromString(serverLocaleDescription);
1764                }
1765
1766                ts = new TopService(this, serviceKey, provider, serviceLocale);
1767                services.addElement(ts);
1768            }
1769
1770            if (SanityManager.DEBUG) {
1771                if (provider != null)
1772                {
1773                    SanityManager.ASSERT(provider.getCanonicalServiceName(serviceName).equals(serviceName),
1774                        "mismatched canonical names " + provider.getCanonicalServiceName(serviceName)
1775                        + " != " + serviceName);
1776                    SanityManager.ASSERT(serviceName.equals(serviceKey.getIdentifier()),
1777                        "mismatched names " + serviceName + " != " + serviceKey.getIdentifier());
1778                }
1779            }
1780
1781
1782            if (properties != null) {
1783
1784                // these properties must not be stored in the persistent properties,
1785
// otherwise moving databases from one directory to another
1786
// will not work. Thus they all have a fixed prefix
1787

1788                // the root of the data
1789
properties.put(PersistentService.ROOT, serviceName);
1790
1791                // the type of the service
1792
properties.put(PersistentService.TYPE, provider.getType());
1793            }
1794
1795            if (SanityManager.DEBUG && reportOn) {
1796                dumpProperties("Service Properties: " + serviceKey.toString(), properties);
1797            }
1798
1799            // push a new context manager
1800
if (previousCM == null) {
1801                cm = contextService.newContextManager();
1802
1803                contextService.setCurrentContextManager(cm);
1804            }
1805            sb = new ServiceBootContext(cm);
1806
1807            UpdateServiceProperties usProperties;
1808            Properties JavaDoc serviceProperties;
1809
1810
1811            //while doing restore from backup, we don't want service properties to be
1812
//updated until all the files are copied from backup.
1813
boolean inRestore = (properties !=null ?
1814                                 properties.getProperty(Property.IN_RESTORE_FROM_BACKUP) != null:false);
1815            
1816            if ((provider != null) && (properties != null)) {
1817                // we need to track to see if the properties have
1818
// been updated or not. If the database is not created yet, we don't create the
1819
// services.properties file yet. We let the following if (create) statement do
1820
//that at the end of the database creation. After that, the changes in
1821
// services.properties file will be tracked by UpdateServiceProperties.
1822
usProperties = new UpdateServiceProperties(provider,
1823                                                           serviceName,
1824                                                           properties,
1825                                                           !(create || inRestore));
1826                serviceProperties = usProperties;
1827            } else {
1828                usProperties = null;
1829                serviceProperties = properties;
1830            }
1831
1832            instance = ts.bootModule(create, null, serviceKey, serviceProperties);
1833
1834            if (create || inRestore) {
1835                // remove all the in-memory properties
1836
provider.saveServiceProperties(serviceName, usProperties.getStorageFactory(),
1837                        BaseMonitor.removeRuntimeProperties(properties), false);
1838                usProperties.setServiceBooted();
1839            }
1840            
1841            if (cm != previousCM)
1842                cm.cleanupOnError(StandardException.closeException());
1843            
1844        } catch (Throwable JavaDoc t) {
1845
1846            // ensure that the severity will shutdown the service
1847
if ((t instanceof StandardException) && (((StandardException) t).getSeverity() == ExceptionSeverity.DATABASE_SEVERITY))
1848                ;
1849            else
1850                t = Monitor.exceptionStartingModule(t);
1851
1852            if (cm != previousCM) {
1853                cm.cleanupOnError(t);
1854            }
1855
1856            if (ts != null) {
1857                ts.shutdown();
1858                synchronized (this) {
1859                    services.removeElement(ts);
1860                }
1861
1862                // Service root will only have been created if
1863
// ts is non-null.
1864
boolean deleteOnError = (properties !=null ?
1865                                         properties.getProperty(Property.DELETE_ROOT_ON_ERROR) !=null:false);
1866                if (create || deleteOnError)
1867                    provider.removeServiceRoot(serviceName);
1868            }
1869
1870
1871            Throwable JavaDoc nested = ((StandardException) t).getNestedException();
1872
1873            // never hide ThreadDeath
1874
if (nested instanceof ThreadDeath JavaDoc)
1875                throw (ThreadDeath JavaDoc) t;
1876
1877            if (nested instanceof StandardException)
1878                throw (StandardException) t;
1879
1880            throw (StandardException) t;
1881
1882        } finally {
1883            if ((previousCM == cm) && (sb != null))
1884                sb.popMe();
1885
1886            if (previousCM == null)
1887                contextService.resetCurrentContextManager(cm);
1888        }
1889
1890        // from this point onwards the service is open for business
1891
ts.setTopModule(instance);
1892
1893        //
1894
// The following yield allows our background threads to
1895
// execute their run methods. This is needed due to
1896
// bug 4081540 on Solaris. When the bug is fixed we can
1897
// remove this yield.
1898
Thread.yield();
1899
1900        return instance;
1901    }
1902
1903    /*
1904    ** Methods of com.ibm.db2j.system.System
1905    */

1906
1907    /**
1908    Return the UUID factory for this system. Returns null
1909    if there isn't one.
1910    See com.ibm.db2j.system.System
1911    */

1912    public UUIDFactory getUUIDFactory() {
1913
1914        return uuidFactory;
1915    }
1916        
1917    /**
1918     * Returns the Timer factory for this system.
1919     *
1920     * @return the system's Timer factory.
1921     */

1922    public TimerFactory getTimerFactory() {
1923        return timerFactory;
1924    }
1925
1926    /*
1927    ** Methods to deal with storing error messages until an InfoStreams is available.
1928    */

1929
1930    private PrintWriter JavaDoc tmpWriter;
1931    private AccessibleByteArrayOutputStream tmpArray;
1932    private boolean dumpedTempWriter;
1933
1934    private PrintWriter JavaDoc getTempWriter() {
1935        if (tmpWriter == null && !dumpedTempWriter) {
1936            tmpArray = new AccessibleByteArrayOutputStream();
1937            tmpWriter = new PrintWriter JavaDoc(tmpArray);
1938        }
1939        return tmpWriter;
1940    }
1941
1942    private void dumpTempWriter(boolean bothPlaces) {
1943
1944        if (tmpWriter == null)
1945            return;
1946
1947        tmpWriter.flush();
1948
1949        BufferedReader JavaDoc lnr = new BufferedReader JavaDoc(
1950            new InputStreamReader JavaDoc(
1951                new ByteArrayInputStream JavaDoc(tmpArray.getInternalByteArray())));
1952        try {
1953            String JavaDoc s;
1954            while ((s = lnr.readLine()) != null) {
1955                if (systemStreams != null)
1956                    systemStreams.stream().printlnWithHeader(s);
1957
1958                if ((systemStreams == null) || bothPlaces)
1959                    logging.println(s);
1960            }
1961        } catch (IOException JavaDoc ioe) {
1962        }
1963
1964        if ((systemStreams == null) || bothPlaces)
1965            logging.flush();
1966
1967        tmpWriter = null;
1968        tmpArray = null;
1969        dumpedTempWriter = true;
1970        logging = null;
1971    }
1972
1973    /**
1974        If the module implements ModuleSupportable then call its
1975        canSupport() method to see if it can or should run in
1976        this setup. If it doesn't then it can always run.
1977    */

1978    static boolean canSupport(Object JavaDoc instance, Properties JavaDoc properties) {
1979        if (instance instanceof ModuleSupportable) {
1980            // see if the instance can support the properties
1981
if (!((ModuleSupportable) instance).canSupport(properties))
1982                return false;
1983        }
1984        return true;
1985    }
1986
1987
1988    /**
1989        Boot a module. If the module implements ModuleControl
1990        then its boot() method is called. Otherwise all the
1991        boot code is assumed to take place in its constructor.
1992    */

1993    static void boot(Object JavaDoc module, boolean create, Properties JavaDoc properties)
1994        throws StandardException {
1995
1996        if (module instanceof ModuleControl)
1997            ((ModuleControl) module).boot(create, properties);
1998    }
1999
2000    /*
2001    ** Locale handling
2002    */

2003    private static Locale JavaDoc staticGetLocaleFromString(String JavaDoc localeDescription)
2004        throws StandardException {
2005
2006        // Check String is of expected format
2007
// even though country should not be optional
2008
// some jvm's support this, so go with the flow.
2009
// xx[_YY[_variant]]
2010

2011        int len = localeDescription.length();
2012
2013        boolean isOk = (len == 2) || (len == 5) || (len > 6);
2014
2015        // must have underscores at position 2
2016
if (isOk && (len != 2))
2017            isOk = localeDescription.charAt(2) == '_';
2018
2019        // must have underscores at position 2
2020
if (isOk && (len > 5))
2021            isOk = localeDescription.charAt(5) == '_';
2022
2023        if (!isOk)
2024            throw StandardException.newException(SQLState.INVALID_LOCALE_DESCRIPTION, localeDescription);
2025
2026        String JavaDoc language = localeDescription.substring(0, 2);
2027        String JavaDoc country = len == 2 ? "" : localeDescription.substring(3, 5);
2028
2029        if (len < 6) {
2030            return new Locale JavaDoc(language, country);
2031        }
2032
2033        String JavaDoc variant = (len > 6) ? localeDescription.substring(6, len) : null;
2034
2035        return new Locale JavaDoc(language, country, variant);
2036    }
2037
2038    private static Locale JavaDoc setLocale(Properties JavaDoc properties)
2039        throws StandardException {
2040
2041        String JavaDoc userDefinedLocale = properties.getProperty(Attribute.TERRITORY);
2042        Locale JavaDoc locale;
2043        if (userDefinedLocale == null)
2044            locale = Locale.getDefault();
2045        else {
2046            // validate the passed in string
2047
locale = staticGetLocaleFromString(userDefinedLocale);
2048        }
2049
2050        properties.put(Property.SERVICE_LOCALE, locale.toString());
2051        return locale;
2052    }
2053
2054    /*
2055    ** BundleFinder
2056    */

2057
2058    //private Hashtable localeBundles;
2059

2060    /**
2061        Get the locale from the ContextManager and then find the bundle
2062        based upon that locale.
2063    */

2064    public ResourceBundle JavaDoc getBundle(String JavaDoc messageId) {
2065        ContextManager cm;
2066        try {
2067            cm = ContextService.getFactory().getCurrentContextManager();
2068        } catch (ShutdownException se) {
2069            cm = null;
2070        }
2071
2072        if (cm != null) {
2073            return MessageService.getBundleForLocale(cm.getMessageLocale(), messageId);
2074        }
2075        return null;
2076    }
2077
2078    public Thread JavaDoc getDaemonThread(Runnable JavaDoc task, String JavaDoc name, boolean setMinPriority) {
2079        Thread JavaDoc t = new Thread JavaDoc(daemonGroup, task, "derby.".concat(name));
2080        t.setDaemon(true);
2081        if (setMinPriority) {
2082            t.setPriority(Thread.MIN_PRIORITY);
2083        }
2084        return t;
2085
2086    }
2087
2088    public void setThreadPriority(int priority) {
2089
2090        Thread JavaDoc t = Thread.currentThread();
2091
2092        if (t.getThreadGroup() == daemonGroup) {
2093            t.setPriority(priority);
2094        }
2095    }
2096
2097    /**
2098        Initialize the monitor wrt the current environemnt.
2099        Returns false if the monitor cannot be initialized, true otherwise.
2100    */

2101    abstract boolean initialize(boolean lite);
2102
2103    class ProviderEnumeration implements Enumeration JavaDoc
2104    {
2105        private Enumeration JavaDoc serviceProvidersKeys = (serviceProviders == null) ? null : serviceProviders.keys();
2106        private Properties JavaDoc startParams;
2107        private Enumeration JavaDoc paramEnumeration;
2108        private boolean enumeratedDirectoryProvider;
2109        private PersistentService storageFactoryPersistentService;
2110
2111        ProviderEnumeration( Properties JavaDoc startParams)
2112        {
2113            this.startParams = startParams;
2114            if( startParams != null)
2115                paramEnumeration = startParams.keys();
2116        }
2117
2118        public Object JavaDoc nextElement() throws NoSuchElementException JavaDoc
2119        {
2120            if( serviceProvidersKeys != null && serviceProvidersKeys.hasMoreElements())
2121                return serviceProviders.get( serviceProvidersKeys.nextElement());
2122            getNextStorageFactory();
2123            Object JavaDoc ret = storageFactoryPersistentService;
2124            storageFactoryPersistentService = null;
2125            return ret;
2126        }
2127
2128        private void getNextStorageFactory()
2129        {
2130            if( storageFactoryPersistentService != null)
2131                return;
2132            if( paramEnumeration != null)
2133            {
2134                while( paramEnumeration.hasMoreElements())
2135                {
2136                    String JavaDoc prop = (String JavaDoc) paramEnumeration.nextElement();
2137                    if( prop.startsWith( Property.SUB_SUB_PROTOCOL_PREFIX))
2138                    {
2139                        try
2140                        {
2141                            String JavaDoc storageFactoryClassName = (String JavaDoc) startParams.get( prop);
2142                            if( storageFactoryClassName != null)
2143                            {
2144                                storageFactoryPersistentService =
2145                                  getPersistentService( (String JavaDoc) startParams.get( prop),
2146                                                        prop.substring( Property.SUB_SUB_PROTOCOL_PREFIX.length()));
2147                                if( storageFactoryPersistentService != null)
2148                                    return;
2149                            }
2150                        }
2151                        catch( StandardException se){};
2152                    }
2153                }
2154            }
2155            if( ! enumeratedDirectoryProvider)
2156            {
2157                try
2158                {
2159                    storageFactoryPersistentService
2160                      = getPersistentService( getStorageFactoryClassName(PersistentService.DIRECTORY),
2161                                              PersistentService.DIRECTORY);
2162                }
2163                catch( StandardException se){ storageFactoryPersistentService = null; }
2164                enumeratedDirectoryProvider = true;
2165            }
2166        } // end of getNextStorageFactory
2167

2168        public boolean hasMoreElements()
2169        {
2170            if( serviceProvidersKeys != null && serviceProvidersKeys.hasMoreElements())
2171                return true;
2172            getNextStorageFactory();
2173            return storageFactoryPersistentService != null;
2174        }
2175    } // end of class ProviderEnumeration
2176
} // end of class BaseMonitor
2177

2178class AntiGC implements Runnable JavaDoc {
2179
2180    boolean goAway;
2181    private Object JavaDoc keep1;
2182
2183    AntiGC(Object JavaDoc a) {
2184        keep1 = a;
2185    }
2186
2187    public void run() {
2188        while (true) {
2189            synchronized (this) {
2190                if (goAway)
2191                    return;
2192                try {
2193                    wait();
2194                } catch (InterruptedException JavaDoc ie) {
2195                }
2196            }
2197        }
2198    }
2199} // end of class AntiGC
2200
Popular Tags