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 }