ContextManager previousCM = contextService.getCurrentContextManager();
ContextManager cm = previousCM;
Object instance;
TopService ts = null;
Context sb = null;
try {
synchronized (this) {
if (inShutdown) {
throw StandardException.newException(SQLState.CLOUDSCAPE_SYSTEM_SHUTDOWN);
}
for (int i = 1; i < services.size(); i++) {
TopService ts2 = (TopService) services.get(i);
if (ts2.isPotentialService(serviceKey)) {
// if the service already exists then just return null
return null;
}
}
Locale serviceLocale = null;
if (create) {
// always wrap the property set in an outer set.
// this ensures that any random attributes from
// a JDBC URL are not written into the service.properties
// file (e.g. like user and password :-)
properties = new Properties(properties);
serviceLocale = setLocale(properties);
properties.put(Property.SERVICE_PROTOCOL, factoryInterface);
serviceName = provider.createServiceRoot(serviceName,
Boolean.valueOf(properties.getProperty(Property.DELETE_ON_CREATE)).booleanValue());
serviceKey = ProtocolKey.create(factoryInterface, serviceName);
} else if (properties != null) {
String serverLocaleDescription = properties.getProperty(Property.SERVICE_LOCALE);
if ( serverLocaleDescription != null)
serviceLocale = staticGetLocaleFromString(serverLocaleDescription);
}
ts = new TopService(this, serviceKey, provider, serviceLocale);
services.add(ts);
}
if (SanityManager.DEBUG) {
if (provider != null)
{
SanityManager.ASSERT(provider.getCanonicalServiceName(serviceName).equals(serviceName),
"mismatched canonical names " + provider.getCanonicalServiceName(serviceName)
+ " != " + serviceName);
SanityManager.ASSERT(serviceName.equals(serviceKey.getIdentifier()),
"mismatched names " + serviceName + " != " + serviceKey.getIdentifier());
}
}
if (properties != null) {
// these properties must not be stored in the persistent properties,
// otherwise moving databases from one directory to another
// will not work. Thus they all have a fixed prefix
// the root of the data
properties.put(PersistentService.ROOT, serviceName);
// the type of the service
properties.put(PersistentService.TYPE, provider.getType());
}
if (SanityManager.DEBUG && reportOn) {
dumpProperties("Service Properties: " + serviceKey.toString(), properties);
}
// push a new context manager
if (previousCM == null) {
cm = contextService.newContextManager();
contextService.setCurrentContextManager(cm);
}
sb = new ServiceBootContext(cm);
UpdateServiceProperties usProperties;
Properties serviceProperties;
//while doing restore from backup, we don't want service properties to be
//updated until all the files are copied from backup.
boolean inRestore = (properties !=null ?
properties.getProperty(Property.IN_RESTORE_FROM_BACKUP) != null:false);
if ((provider != null) && (properties != null)) {
// we need to track to see if the properties have
// been updated or not. If the database is not created yet, we don't create the
// services.properties file yet. We let the following if (create) statement do
//that at the end of the database creation. After that, the changes in
// services.properties file will be tracked by UpdateServiceProperties.
usProperties = new UpdateServiceProperties(provider,
serviceName,
properties,
!(create || inRestore));
serviceProperties = usProperties;
} else {
usProperties = null;
serviceProperties = properties;
}
instance = ts.bootModule(create, null, serviceKey, serviceProperties);
if (create || inRestore) {
// remove all the in-memory properties
provider.saveServiceProperties(serviceName, usProperties.getStorageFactory(),
BaseMonitor.removeRuntimeProperties(properties), false);
usProperties.setServiceBooted();
}
if (cm != previousCM) {
//Assume database is not active. DERBY-4856 thread dump
cm.cleanupOnError(StandardException.closeException(), false);
}
} catch (Throwable t) {
StandardException se;
// ensure that the severity will shutdown the service
if ((t instanceof StandardException) && (((StandardException) t).getSeverity() == ExceptionSeverity.DATABASE_SEVERITY))
se = (StandardException) t;
else
se = Monitor.exceptionStartingModule(t);
if (cm != previousCM) {
//Assume database is not active. DERBY-4856 thread dump
cm.cleanupOnError(se, false);
}
if (ts != null) {
ts.shutdown();
synchronized (this) {
services.remove(ts);
}
// Service root will only have been created if
// ts is non-null.
boolean deleteOnError = (properties !=null ?
properties.getProperty(Property.DELETE_ROOT_ON_ERROR) !=null:false);
if (create || deleteOnError)
provider.removeServiceRoot(serviceName);
}
Throwable nested = se.getCause();
// never hide ThreadDeath
if (nested instanceof ThreadDeath)
throw (ThreadDeath) nested;
throw se;
} finally {
if ((previousCM == cm) && (sb != null))
sb.popMe();
if (previousCM == null)
contextService.resetCurrentContextManager(cm);
}