Docjar: A Java Source and Docuemnt Enginecom.*    java.*    javax.*    org.*    all    new    plug-in

Quick Search    Search Deep

Source code: org/apache/derby/iapi/services/monitor/Monitor.java


1   /*
2   
3      Derby - Class org.apache.derby.iapi.services.monitor.Monitor
4   
5      Copyright 1997, 2004 The Apache Software Foundation or its licensors, as applicable.
6   
7      Licensed under the Apache License, Version 2.0 (the "License");
8      you may not use this file except in compliance with the License.
9      You may obtain a copy of the License at
10  
11        http://www.apache.org/licenses/LICENSE-2.0
12  
13     Unless required by applicable law or agreed to in writing, software
14     distributed under the License is distributed on an "AS IS" BASIS,
15     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16     See the License for the specific language governing permissions and
17     limitations under the License.
18  
19   */
20  
21  package org.apache.derby.iapi.services.monitor;
22  
23  import org.apache.derby.iapi.error.StandardException;
24  import org.apache.derby.iapi.services.i18n.MessageService;
25  import org.apache.derby.iapi.services.sanity.SanityManager;
26  import org.apache.derby.iapi.services.stream.HeaderPrintWriter;
27  import org.apache.derby.iapi.services.info.ProductGenusNames;
28  import org.apache.derby.iapi.services.info.ProductVersionHolder;
29  import org.apache.derby.iapi.reference.EngineType;
30  import org.apache.derby.iapi.reference.Attribute;
31  import org.apache.derby.iapi.services.property.PropertyUtil;
32  
33  import org.apache.derby.iapi.services.loader.InstanceGetter;
34  
35  import org.apache.derby.iapi.reference.SQLState;
36  import org.apache.derby.iapi.reference.Property;
37  
38  import java.util.Properties;
39  import java.util.Locale;
40  import java.io.PrintStream;
41  
42  /**
43    <P><B>Services</B><BR>
44  
45    A service is a collection of modules that combine to provide
46    the full functionality defined by the service. A service is defined
47    by three pieces of information:
48    <OL>
49    <LI>A fully qualified java class name that identifies the functionality or API
50    that the service must provide. Typically this class represents a java interface.
51    This class name is termed the <EM>factory interface</EM>.
52    <LI>The <EM>identifier</EM> of the service. Services are identified by a String, this may
53    be hard-coded, come from a UUID or any other source.
54    <LI>An optional java.util.Properties set.
55    </OL>
56    <BR>
57    The running functionality of the service is provided by a module
58    that implements the factory interface. The identifier of the this module
59    is not (need not be) the same as the identifier of the service. The identifier
60    of the service is held by the monitor in its service tables.
61    <BR>
62    Each module in a service is keyed by at least one factory interface, identifier}
63    pair. This pair is guaranteed to be unique within the service.
64    <BR>
65    The lifetime of a module in a service is no longer than the lifetime of the service.
66    Thus shutting down a service shuts down all the modules within a service.
67    <B>Optionally - </B> an individual module within a service may be shutdown, this will
68    in turn shutdown any modules it started if those module are not in use by other
69    modules within the service. This would be handled by the monitor, not the module itself.
70    <BR>
71    A service may be persistent, it goes through a boot in create mode, and subsequently boot
72    in non-create mode, or a non-peristent service, it always boots in non-create mode.
73    Persistent services can store their re-start parameters in their properties set, the monitor
74    provides the persistent storage of the properties set.
75    Non-persistent services do not have a properties set.
76  
77    <P><B>Booting Services</B><BR>
78    Services can be booted a number of ways
79    <UL>
80    <LI>A non-persistent service can be booted by having a property in the application properties
81    or the system (JVM) set.
82    <PRE>
83    derby.service.<EM>service name</EM>=<EM>class name</EM>
84    e.g.
85    # Added to the properties automatically by the class org.apache.derby.jdbc.EmbeddedDriver
86    derby.service.jdbc=java.sql.Driver
87    </PRE>
88    <LI>A persistent service can be booted by having a property in the application properties
89    or the system (JVM) set.
90    <PRE>
91    derby.service.<EM>service name</EM>=<EM>persistent storage type</EM>
92    e.g.
93    derby.service.mydatabase=serviceDirectory
94    </PRE>
95    serviceDirectory is a type understood by the monitor which means that there is a directory
96    named mydatabase within the system directory and within it is a properties file service.properties. This properties
97    set is the set for the service and must contain a property
98    <PRE>
99    derby.protocol=<EM>class name</EM>
100   </PRE>
101   This is then the factory interface for the service. Other storage types could be added in
102   the future.
103   <LI>
104   The monitor at start time looks for all persistent services that it can find and starts them.
105   E.g. all directories in the system directory that have a file service.properties are started
106   as services.
107   <LI>Services are started on demand, e.g. a findService attempts to boot a service if it
108   cannot be found.
109   </UL>
110   <B>Any or all of these three latter methods can be implemented. A first release may
111   just implement the look for all services and boot them.</B>
112   .
113   <P><B>System Service</B><BR>
114   A special service exists, the System Service. This service has no factory interface,
115   no identifier and no Properties set. It allows modules to be started that are required
116   by another service (or the monitor itself) but are not fundamentally part of the service.
117   Modules within this service are unidentified.
118   Typically these modules are system wide types of functionality like streams, uuid creation etc.
119   <BR>
120   The lifetime of a system module is the lifetime of the monitor.
121   <B>Optionally - </B> this could be changed to reference count on individual modules, requires
122   some minor api changes.
123 
124   <P><B>Modules</B><BR>
125 
126   A module is found or booted using four pieces of information:
127   <OL>
128   <LI>The service the module lives in or will live in.
129   <LI>A fully qualified java class name that identifies the functionality or API
130   that the module must provide. Typically this class represents a java interface.
131   This class name is termed the <EM>factory interface</EM>.
132   <LI>The <EM>identifier</EM> of the module. Modules are identified by a String, this may
133   be null, be hard-coded, come from a UUID or any other source. If the identifier
134   is null then the module is described as <EM>unidentified</EM>.
135   <LI>Boot time only - A java.util.Properties set. This Properties set is service wide
136   and typically contains parameters used to determine module implementation or runtime
137   behaviour.
138   </OL>
139   <BR>
140   The service is identified by explicitly identifiying the System Service or
141   by providing a reference to a module that already exists with the required service.
142   <BR>
143   The factory interface is provided by a String constant of the form class.MODULE
144   from the required interface.
145   <BR>
146   The module identifier is provided in a fashion determined by the code, in most
147   cases a unidentified module will suffice.
148   <BR>
149   The Properties set is also determined in a fashion determined by the code at
150   create or add service time.
151 
152   <P><B>Module Implementations</B><BR>
153 
154   When creating an instance of a module, an implementation is found through lists of
155   potential implementations.
156   <BR>
157   A list of potential implementations is obtained from a Properties set. Any property
158   within this set that is of the form
159   <PRE>
160   derby.module.<EM>tag</EM>=<EM>java class name</EM>
161   </PRE>
162   is seen by the monitor as a possible implementation. <EM>tag</EM> has no meaning within
163   the monitor, it is only there to provide uniqueness within the properties file. Typically
164   the tag is to provide some description for human readers of the properties file, e.g.
165   derby.module.lockManager for an implementation of a lock manager.
166   <BR>
167   The monitor looks through four properties sets for lists of potential implementations in this
168   order. 
169   <OL>
170   <LI>The properties set of the service (i.e. that passed into Monitor.createPersistentService()
171   or Monitor.startService()).
172   <LI>The System (JVM) properties set (i.e. java.lang.System.getProperties()).
173   <LI>The application properties set (i.e. obtained from the cloudscape.properties file).
174   <LI>The default implementation properties set (i.e. obtained from the
175   /org/apache/derby/modules.properties resource).
176   </OL>
177   Any one of the properties can be missing or not have any implementations listed within it.
178   <BR>
179   Every request to create an instance of a module searches the four implementation
180   lists in the order above. Which list the current running code or the passed in service
181   module came from is not relevant.
182   <BR>
183   Within each list of potential implementations the search is conducted as follows:
184   <OL>
185   <LI>Attempt to load the class, if the class cannot be loaded skip to the next potential
186   implementation.
187   <LI>See if the factory interface is assignable from the class (isAssignableFrom() method
188   of java.lang.Class), if not skip to the next potential implementation.
189   <LI>See if an instance of the class can be created without any exceptions (newInstance() method
190   of java.lang.Class), if not skip to the next potential implementation.
191   <LI>[boot time only] See if the canSupport() method of ModuleControl returns true when called with the
192   Properties set of the service, if not skip to the next potential implementation.
193   </OL>
194   If all these checks pass then the instance is a valid implementation and its boot() method
195   of ModuleControl is called to activate it. Note that the search order within
196   the list obtained from a Properties set is not guaranteed.
197 
198    <P><B>Module Searching</B><BR>
199 
200   When searching for a module the search space is always restricted to a single service.
201   This service is usually the system service or the service of the module making the
202   search request. It would be very rare (wrong?) to search for a module in a service that
203   was not the current service and not the system service.
204   <BR>
205   Within the list of modules in the service the search is conducted as follows:
206   <OL>
207   <LI>See if the instance of the module an instance of the factory interface (isInstance() method
208   of java.lang.Class), if not skip to the next module.
209   <LI>See if the identifier of the module matches the required identifier, if not skip to the next module.
210   <LI>See if the canSupport() method of ModuleControl returns true when called with the
211   Properties set of the service, if not skip to the next module.
212   </OL>
213   Note that no search order of the modules is guaranteed.
214   <BR>
215   Also note that a module may be found by a different factory interface to the one
216   it was created under. Thus a class may implement multiple factory interfaces, its boot
217   method has no knowledge of which factory interface it was requested by.
218 
219   <P><B>Service Properties</B><BR>
220 
221   Within the service's Properties a module may search for its parameters. It identifies
222   its parameters using a unqiue parameter name and its identifier.
223   <BR>
224   Unique parameter names are made unique through the 'dot' convention of Properties
225   files. A module protocol picks some unique key portion to start, e.g. RawStore for the RawStoreFactory
226   and then extends that for specific parameters, e.g. RawStore.PageSize. Thus
227   parameters that are typically understood by all implementations of that protocol would
228   start with that key portion. Parameters for specific implementations add another key portion
229   onto the protocol key portion, e.g. RawStore.FileSystem for an file system implementation
230   of the raw store, with a specific parameter being RawStore.FileSystem.SectorSize.
231 
232   <BR>These are general guidelines, UUID's could be used as the properties keys but
233   would make the parameters hard to read.
234   <BR>
235   When a module is unidentified it should look for a parameter using just
236   the property key for that parameter, e.g. getProperty("RawStore.PageSize").
237   <BR>
238   When a module has an identifier is should look for a property using the
239   key with a dot and the identifier appended, e.g. getProperty("RawStore.PageSize" + "." + identifier).
240   <BR>
241   In addition to searching for parameters in the service properties set, the system and
242   application set may be searched using the getProperty() method of ModuleFactory.
243   <BR><B>Should any order be defined for this, should it be automatic?</B>
244 */
245 public class Monitor {
246 
247   public static final String SERVICE_TYPE_DIRECTORY = "serviceDirectory";
248 
249   public static final Object syncMe = new Object();
250 
251   /**
252     Global debug flag to turn on tracing of reads calls newInstanceFromIdentifier()
253     */
254   public final static String
255     NEW_INSTANCE_FROM_ID_TRACE_DEBUG_FLAG = SanityManager.DEBUG ? "MonitorNewInstanceFromId" : null;
256   
257   public static final String DEBUG_TRUE = SanityManager.DEBUG ? "derby.debug.true" : null;
258   public static final String DEBUG_FALSE = SanityManager.DEBUG ? "derby.debug.false" : null;
259 
260 
261   private static ModuleFactory monitor;
262   private static boolean active;
263 
264   public Monitor() {
265   }
266 
267   /**
268     Start a Monitor based software system.
269 
270     This method will execute the following steps.
271 
272   <OL>
273   <LI> Create an instance of a module (monitor) of the required implementation.
274   <LI> Start the monitor which will in turn start any requested services
275   <LI> Execute the run() method of startCode (if startCode was not null).
276   <LI> Return.
277   </OL>
278   <P> If MonitorBoot.start() is called more then once then subsequent calls
279   have no effect.
280 
281     @param properties The application properties
282     @param logging Where to place initial error output. This location will be used
283       until an InfoStreams module is successfully started.
284   */
285 
286   public static void startMonitor(Properties bootProperties, PrintStream logging) {
287 
288     new org.apache.derby.impl.services.monitor.FileMonitor(bootProperties, logging);      
289   }
290   /**
291     Initialise this class, must only be called by an implementation
292     of the monitor (ModuleFactory).
293   */
294   public static boolean setMonitor(ModuleFactory theMonitor) {
295 
296     synchronized (syncMe) {
297       if (active)
298         return false;
299 
300       monitor = theMonitor;
301       active = true;
302       return true;
303     }
304   }
305 
306   public static void clearMonitor() {
307     // the monitor reference needs to remain valid
308     // as there are some accesses to getMonitor()
309     // after the system has been shutdown.
310     synchronized (syncMe) {
311       active = false;
312     }
313   }
314 
315   /**
316     Get the monitor.
317   */
318   public static ModuleFactory getMonitor() {
319     return monitor;
320   }
321   public static ModuleFactory getMonitorLite() {
322     synchronized (syncMe) {
323       if (active && monitor != null)
324         return monitor;
325     }
326 
327     // initialize a monitor just to get system properties
328     // with the right secuirty checks and the correct sematics
329     // for lookup of derby.system.home.
330     // This instance will be discarded once it is used.        ;
331 
332     return new org.apache.derby.impl.services.monitor.FileMonitor();
333   }
334 
335   public static HeaderPrintWriter getStream() {
336     return monitor.getSystemStreams().stream();
337   }
338 
339   /**
340     Return the name of the service that the passed in module lives in.
341   */
342   public static String getServiceName(Object serviceModule) {
343     return monitor.getServiceName(serviceModule);
344   }
345 
346 
347   /**
348     Start or find a module in the system service. This call allows modules
349     to explictly start services they require.
350     If no module matching the criteria is found (see this class's prologue for details)
351     then an instance will be created (see prologue) and booted as follows.
352     <PRE>
353     ((ModuleControl) instance).boot(false, (String) null, (Properties) null);
354     </PRE>
355 
356     @return a reference to a module.
357 
358     @exception StandardException An attempt to start the module failed.
359 
360     @see ModuleControl#boot
361   */
362   public static Object startSystemModule(String factoryInterface)
363     throws StandardException {
364 
365     Object module = monitor.startModule(false, (Object) null, factoryInterface, (String) null, (Properties) null);
366     
367     if (SanityManager.DEBUG) {
368       SanityManager.ASSERT(module != null, "module is null - " + factoryInterface);
369     }
370 
371     return module;
372   }
373 
374   /**
375     Find a module in the system service.
376 
377     @return a reference to a module or null if one cannot be found.
378   */
379   public static Object findSystemModule(String factoryInterface) throws StandardException
380   {
381     Object module = getMonitor().findModule((Object) null,
382                     factoryInterface, (String) null);
383     if (module == null)
384       throw Monitor.missingImplementation(factoryInterface);
385 
386     return module;
387   }
388 
389   public static Object getSystemModule(String factoryInterface)
390   {
391     Object module = getMonitor().findModule((Object) null,
392                     factoryInterface, (String) null);
393     return module;
394   }
395 
396   /**
397     Boot or find a unidentified module within a service. This call allows modules
398     to start or create any modules they explicitly require to exist within
399     their service. If no module matching the criteria is found (see this class's prologue for details)
400     then an instance will be created (see prologue) and booted as follows.
401     <PRE>
402     ((ModuleControl) instance).boot(create, (String) null, properties);
403     </PRE>
404     <BR>
405     The service is defined by the service that the module serviceModule lives in,
406     typically this call is made from the boot method of a module and thus
407     'this' is passed in for serviceModule.
408 
409     @return a reference to a module.
410 
411     @exception StandardException An attempt to start the module failed.
412 
413   */
414   public static Object bootServiceModule(boolean create, Object serviceModule,
415     String factoryInterface, Properties properties)
416     throws StandardException {
417 
418     Object module = monitor.startModule(create, serviceModule, factoryInterface,
419             (String) null, properties);
420 
421     if (SanityManager.DEBUG) {
422       SanityManager.ASSERT(module != null, "module is null - " + factoryInterface);
423     }
424 
425     return module;
426   }
427 
428   /**
429     Boot or find a identified module within a service. This call allows modules
430     to start or create any modules they explicitly require to exist within
431     their service. If no module matching the criteria is found (see this class's prologue for details)
432     then an instance will be created (see prologue) and booted as follows.
433     <PRE>
434     ((ModuleControl) instance).boot(create, identifer, properties);
435     </PRE>
436     <BR>
437     The service is defined by the service that the module serviceModule lives in,
438     typically this call is made from the boot method of a module and thus
439     'this' is passed in for serviceModule.
440 
441     @return a reference to a module.
442 
443     @exception StandardException An attempt to start the module failed.
444 
445   */
446   public static Object bootServiceModule(boolean create, Object serviceModule,
447     String factoryInterface, String identifier, Properties properties)
448     throws StandardException {
449 
450     Object module = monitor.startModule(create, serviceModule, factoryInterface, identifier, properties);
451     
452     if (SanityManager.DEBUG) {
453       SanityManager.ASSERT(module != null, "module is null - " + factoryInterface);
454     }
455 
456     return module;
457   }
458 
459   /**
460     Find an unidentified module within a service.
461     <BR>
462     The service is defined by the service that the module serviceModule lives in.
463 
464     @return a reference to a module or null if one cannot be found.
465 
466   */
467   public static Object findServiceModule(Object serviceModule, String factoryInterface)
468     throws StandardException {
469     Object module = getMonitor().findModule(serviceModule, factoryInterface, (String) null);
470     if (module == null)
471       throw Monitor.missingImplementation(factoryInterface);
472     return module;
473   }
474   public static Object getServiceModule(Object serviceModule, String factoryInterface)
475   {
476     Object module = getMonitor().findModule(serviceModule, factoryInterface, (String) null);
477     return module;
478   }
479 
480   /**
481     Find an identified module within a service.
482     <BR>
483     The service is defined by the service that the module serviceModule lives in.
484 
485     @return a reference to a module or null if one cannot be found.
486 
487   */
488   //public static Object findServiceModule(Object serviceModule, String factoryInterface, String identifier) {
489   //  return monitor.findModule(serviceModule, factoryInterface, identifier);
490   //}
491 
492 
493   /**
494     Find a service.
495 
496     @return a refrence to a module represeting the service or null if the service does not exist.
497 
498   */
499   public static Object findService(String factoryInterface, String serviceName) {
500     return monitor.findService(factoryInterface, serviceName);
501   }
502 
503   /**
504     Start a persistent service. The name of the service can include a
505     service type, in the form 'type:serviceName'.
506     <BR>
507     Note that the return type only indicates
508     if the service can be handled by the monitor. It does not indicate
509     the service was started successfully. The cases are
510     <OL>
511     <LI> Service type not handled - false returned.
512     <LI> Service type handled, service does not exist, true returned.
513     <LI> Service type handled, service exists and booted OK, true returned.
514     <LI> Service type handled, service exists and failed to boot, exception thrown.
515     </OL>
516 
517     If true is returned then findService should be used to see if the service
518     exists or not.
519 
520     @return true if the service type is handled by the monitor, false if it isn't
521 
522     @exception StandardException An attempt to start the service failed.
523   */
524 
525   public static boolean startPersistentService(String serviceName, 
526                          Properties properties) 
527     throws StandardException {
528 
529     if (SanityManager.DEBUG) {
530       SanityManager.ASSERT(serviceName != null, "serviceName is null");
531     }
532 
533     return monitor.startPersistentService(serviceName, properties);
534   }
535 
536   /**
537     Start a non-persistent service. 
538     <P><B>Context</B><BR>
539     A context manager will be created and installed at the start of this method and destroyed
540     just before this method returns.
541 
542     @return The module from the service if it was started successfully. 
543 
544     @exception StandardException An exception was thrown trying to start the service.
545   */
546   public static Object startNonPersistentService(String factoryInterface, String serviceName, Properties properties)
547     throws StandardException {
548 
549     if (SanityManager.DEBUG) {
550       SanityManager.ASSERT(factoryInterface != null, "serviceName is null");
551       SanityManager.ASSERT(serviceName != null, "serviceName is null");
552     }
553 
554     return monitor.startNonPersistentService(factoryInterface, serviceName, properties);
555   }
556 
557   /**
558     Create a named service that implements the java interface (or class) fully qualified by factoryInterface.
559     The Properties object specifies create time parameters to be used by the modules within the
560     service. Any module created by this service may add or remove parameters within the
561     properties object in their ModuleControl.boot() method. The properties set will be saved
562     by the Monitor for later use when the monitor is started.
563     <P><B>Context</B><BR>
564     A context manager will be created and installed at the start of this method and destroyed
565     just before this method returns.
566 
567     @return The module from the service if it was created successfully, null if a service already existed. 
568 
569     @exception StandardException An exception was thrown trying to create the service.
570   */
571   public static Object createPersistentService(String factoryInterface, String serviceName, Properties properties) 
572     throws StandardException {
573 
574     if (SanityManager.DEBUG) {
575       SanityManager.ASSERT(factoryInterface != null, "serviceName is null");
576       SanityManager.ASSERT(serviceName != null, "serviceName is null");
577     }
578     
579     return monitor.createPersistentService(factoryInterface, serviceName, properties);
580   }
581     public static void removePersistentService(String name)
582         throws StandardException
583     {
584     monitor.removePersistentService(name);
585     }
586 
587   /**
588     Obtain the class object for a class that supports the given identifier.
589 
590     If no class has been registered for the identifier then a StandardException
591     is thrown with no attached java.lang exception (nextException).
592     If a problem loading or accessing the class is obtained then a StandardException
593     is thrown with the real java.lang exception attached.
594 
595     @return a valid class object
596 
597     @exception StandardException See text above.
598   */
599   public static InstanceGetter classFromIdentifier(int identifier) 
600     throws StandardException {
601     return monitor.classFromIdentifier(identifier);
602   }
603 
604   /**
605     Obtain an new instance of a class that supports the given identifier.
606 
607     If no class has been registered for the identifier then a StandardException
608     is thrown with no attached java.lang exception (getNestedException).
609     If a problem loading or accessing the class or creating the object is obtained
610     then a StandardException is thrown with the real java.lang exception attached.
611 
612     @return a reference to a newly created object
613 
614     @exception StandardException See text above.
615   */
616   public static Object newInstanceFromIdentifier(int identifier) 
617     throws StandardException {
618     return monitor.newInstanceFromIdentifier(identifier);
619   }
620 
621 
622   /* 
623   ** Static methods for startup type exceptions.
624   */
625     /**
626     return a StandardException to indicate that a module failed to
627     start because it could not obtain the version of a required product.
628 
629     @param productGenusName The genus name of the product.
630     @return The exception.
631   */
632   public static StandardException missingProductVersion(String productGenusName)
633   {
634     return StandardException.newException(SQLState.MISSING_PRODUCT_VERSION, productGenusName);
635   }
636 
637   /**
638     return a StandardException to indicate a missing
639     implementation.
640 
641     @param implementation the module name of the missing implementation.
642 
643     @return The exception.
644   */
645   public static StandardException missingImplementation(String implementation) 
646   {
647     return StandardException.newException(SQLState.SERVICE_MISSING_IMPLEMENTATION, implementation);
648   }
649 
650   /**
651     return a StandardException to indicate that an exception caused
652     starting the module to fail.
653 
654     @param t the exception which caused starting the module to fail.
655 
656     @return The exception.
657   */
658   public static StandardException exceptionStartingModule(Throwable t)
659   {
660     return StandardException.newException(SQLState.SERVICE_STARTUP_EXCEPTION, t);
661   }
662 
663   public static void logMessage(String messageText) {
664     getStream().println(messageText);
665   }
666 
667   public static void logTextMessage(String messageID) {
668     getStream().println(MessageService.getTextMessage(messageID));
669   }
670   public static void logTextMessage(String messageID, Object a1) {
671     getStream().println(MessageService.getTextMessage(messageID, a1));
672   }
673   public static void logTextMessage(String messageID, Object a1, Object a2) {
674     getStream().println(MessageService.getTextMessage(messageID, a1, a2));
675   }
676   public static void logTextMessage(String messageID, Object a1, Object a2, Object a3) {
677     getStream().println(MessageService.getTextMessage(messageID, a1, a2, a3));
678   }
679   public static void logTextMessage(String messageID, Object a1, Object a2, Object a3, Object a4) {
680     getStream().println(MessageService.getTextMessage(messageID, a1, a2, a3, a4));
681   }
682 
683   /**
684    *  Translate a localeDescription of the form ll[_CC[_variant]] to
685    *  a Locale object.
686    */
687   public static Locale getLocaleFromString(String localeDescription)
688                 throws StandardException {
689     return monitor.getLocaleFromString(localeDescription);
690   }
691 
692 
693   /**
694     Single point for checking if an upgrade is allowed.
695     @return true a full upgrade has been requested, false soft upgrade mode is active.
696    */
697   public static boolean isFullUpgrade(Properties startParams, String oldVersionInfo) throws StandardException {
698 
699     boolean fullUpgrade = Boolean.valueOf(startParams.getProperty(org.apache.derby.iapi.reference.Attribute.UPGRADE_ATTR)).booleanValue();
700 
701     ProductVersionHolder engineVersion = Monitor.getMonitor().getEngineVersion();
702 
703     if (engineVersion.isBeta() || engineVersion.isAlpha()) {
704           
705       if (!PropertyUtil.getSystemBoolean(Property.ALPHA_BETA_ALLOW_UPGRADE))
706       {
707         //  upgrade not supported for alpha/beta.
708         throw StandardException.newException(SQLState.UPGRADE_UNSUPPORTED,
709             oldVersionInfo, engineVersion.getSimpleVersionString());
710       }
711     }
712 
713     return fullUpgrade;
714   }
715 
716   /**
717     *
718     *  @param  startParams      startup parameters
719     *  @param  desiredProperty    property we're interested in
720     *
721     *  @return  true    type is as desired.
722     *      false    otherwise
723     *
724     */
725   public static boolean isDesiredType(Properties startParams, int desiredProperty )
726   {
727     boolean  retval = false;
728     int    engineType = EngineType.NONE;
729 
730     if ( startParams != null )
731     {
732       engineType = Monitor.getEngineType( startParams );
733     }
734 
735     return (engineType & desiredProperty) != 0;
736   }
737   public static boolean isDesiredType(int engineType, int desiredProperty) {
738     return (engineType & desiredProperty) != 0;
739   }
740   
741   /**
742     *  @param  startParams    startup parameters
743     *
744     *  @return  type of engine
745     *
746     */
747 
748   static  public  int  getEngineType(Properties startParams)
749   {
750     if ( startParams != null )
751     {
752       String etp = startParams.getProperty(EngineType.PROPERTY);
753 
754       int engineType = etp == null ? EngineType.STANDALONE_DB : Integer.parseInt(etp.trim());
755 
756       return engineType;
757     }
758 
759     return EngineType.STANDALONE_DB;
760   }
761 
762   /**
763     Return true if the properties set provided contains
764     database creation attributes for a database
765     of the correct type
766     */
767   public static boolean isDesiredCreateType(Properties p, int type)
768   {
769     boolean plainCreate = Boolean.valueOf(p.getProperty(Attribute.CREATE_ATTR)).booleanValue();
770 
771     if (plainCreate) {
772       return (type & EngineType.NONE) != 0;
773     }
774 
775     // database must already exist
776     return isDesiredType(p, type);
777   }
778 }