if (openNew) {
database = null;
} else {
database = DATABASES.get(name);
}
User user = null;
boolean opened = false;
if (database == null) {
if (ifExists && !Database.exists(name)) {
throw DbException.get(ErrorCode.DATABASE_NOT_FOUND_1, name);
}
database = createDatabase();
database.init(ci, cipher);
opened = true;
if (database.getAllUsers().size() == 0) {
// users is the last thing we add, so if no user is around,
// the database is new (or not initialized correctly)
user = new User(database, database.allocateObjectId(), ci.getUserName(), false);
user.setAdmin(true);
user.setUserPasswordHash(ci.getUserPasswordHash());
database.setMasterUser(user);
}
DATABASES.put(name, database);
}
synchronized (database) {
if (opened) {
// start the thread when already synchronizing on the database
// otherwise a deadlock can occur when the writer thread
// opens a new database (as in recovery testing)
database.opened();
}
if (database.isClosing()) {
return null;
}
if (user == null) {
if (database.validateFilePasswordHash(cipher, ci.getFilePasswordHash())) {
user = database.findUser(ci.getUserName());
if (user != null) {
if (!user.validateUserPasswordHash(ci.getUserPasswordHash())) {
user = null;
}
}
}
if (opened && (user == null || !user.isAdmin())) {
// reset - because the user is not an admin, and has no
// right to listen to exceptions
database.setEventListener(null);
}
}