Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance. Project price only 1 $
You can buy this project and download/modify it how often you want.
package io.sirix.access;
import io.sirix.api.*;
import io.sirix.api.json.JsonResourceSession;
import io.sirix.api.xml.XmlResourceSession;
import io.sirix.cache.BufferManager;
import io.sirix.exception.SirixIOException;
import io.sirix.exception.SirixUsageException;
import io.sirix.utils.LogWrapper;
import io.sirix.utils.SirixFiles;
import org.slf4j.LoggerFactory;
import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.UUID;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import static java.util.Objects.requireNonNull;
/**
* Utility methods for {@link Database} handling.
*
* @author Johannes Lichtenberger
* @author Sebastian Graf, University of Konstanz
*/
public final class Databases {
/**
* Private constructor to prevent instantiation.
*/
private Databases() {
throw new AssertionError("May not be instantiated!");
}
private static final LogWrapper logger = new LogWrapper(LoggerFactory.getLogger(Databases.class));
/**
* Buffer managers / page cache for each resource.
*/
private static final ConcurrentMap> BUFFER_MANAGERS = new ConcurrentHashMap<>();
/**
* DI component that manages the database.
*/
static final DatabaseManager MANAGER = DaggerDatabaseManager.create();
/**
* Get the database type
*
* @param file the database file
* @return the type of the database
*/
public static DatabaseType getDatabaseType(final Path file) {
return DatabaseConfiguration.deserialize(file).getDatabaseType();
}
/**
* Creates an XML-database. This includes loading the database configuration, building up the
* structure and preparing everything for login.
*
* @param dbConfig config which is used for the database, including storage location
* @return true if creation is valid, false otherwise
* @throws SirixIOException if something odd happens within the creation process.
*/
public static synchronized boolean createXmlDatabase(final DatabaseConfiguration dbConfig) {
return createTheDatabase(dbConfig.setDatabaseType(DatabaseType.XML));
}
/**
* Creates a JSON-database. This includes loading the database configuration, building up the
* structure and preparing everything for login.
*
* @param dbConfig config which is used for the database, including storage location
* @return true if creation is valid, false otherwise
* @throws SirixIOException if something odd happens within the creation process.
*/
public static synchronized boolean createJsonDatabase(final DatabaseConfiguration dbConfig) {
return createTheDatabase(dbConfig.setDatabaseType(DatabaseType.JSON));
}
private static boolean createTheDatabase(final DatabaseConfiguration dbConfig) {
boolean returnVal = true;
// if file is existing, skipping
final var databaseFile = dbConfig.getDatabaseFile();
if (Files.exists(databaseFile) && !SirixFiles.isDirectoryEmpty(databaseFile)) {
returnVal = false;
} else {
try {
Files.createDirectories(databaseFile);
} catch (UnsupportedOperationException | IOException | SecurityException e) {
returnVal = false;
}
if (returnVal) {
// creation of folder structure
for (final DatabaseConfiguration.DatabasePaths paths : DatabaseConfiguration.DatabasePaths.values()) {
final Path toCreate = databaseFile.resolve(paths.getFile());
if (paths.isFolder()) {
try {
Files.createDirectory(toCreate);
} catch (UnsupportedOperationException | IOException | SecurityException e) {
returnVal = false;
}
} else {
try {
if (!toCreate.getFileName().equals(DatabaseConfiguration.DatabasePaths.LOCK.getFile().getFileName())) {
Files.createFile(toCreate);
}
} catch (final IOException e) {
SirixFiles.recursiveRemove(databaseFile);
throw new SirixIOException(e);
}
}
if (!returnVal) {
break;
}
}
}
// serialization of the config
DatabaseConfiguration.serialize(dbConfig);
// if something was not correct, delete the partly created
// substructure
if (!returnVal) {
SirixFiles.recursiveRemove(databaseFile);
}
}
return returnVal;
}
/**
* Delete a database. This deletes all relevant data. All running sessions must be closed
* beforehand.
*
* @param dbFile the database at this path should be deleted
* @throws SirixIOException if Sirix fails to delete the database
*/
public static synchronized void removeDatabase(final Path dbFile) {
// check that database must be closed beforehand and if file is existing and folder is a sirix-database, delete it
if (!MANAGER.sessions().containsAnyEntry(dbFile) && Files.exists(dbFile)) {
if (DatabaseConfiguration.DatabasePaths.compareStructure(dbFile) == 0) {
final var databaseConfiguration = DatabaseConfiguration.deserialize(dbFile);
final var databaseType = databaseConfiguration.getDatabaseType();
switch (databaseType) {
case XML -> removeXmlResources(dbFile);
case JSON -> removeJsonResources(dbFile);
default -> throw new IllegalStateException("Database type unknown!");
}
}
ConcurrentMap bufferManagers = BUFFER_MANAGERS.remove(dbFile);
if (bufferManagers != null && !bufferManagers.isEmpty()) {
// TODO: Why is this necessary? BUG!
bufferManagers.values().forEach(BufferManager::clearAllCaches);
}
SirixFiles.recursiveRemove(dbFile);
}
}
private static void removeJsonResources(Path dbFile) {
try (final Database> database = openJsonDatabase(dbFile)) {
removeResources(database);
}
}
private static void removeXmlResources(Path dbFile) {
try (final Database> database = openXmlDatabase(dbFile)) {
removeResources(database);
}
}
private static void removeResources(Database> database) {
final var resourcePaths = database.listResources();
for (final var resourcePath : resourcePaths) {
database.removeResource(resourcePath.getFileName().toString());
}
}
/**
* Open database. A database can be opened only once (even across JVMs). Afterwards a singleton
* instance bound to the {@link File} is returned.
*
* @param file determines where the database is located
* @param user user used to open the database
* @return {@link Database} instance.
* @throws SirixIOException if an I/O exception occurs
* @throws SirixUsageException if Sirix is not used properly
* @throws NullPointerException if {@code file} is {@code null}
*/
public static synchronized Database openXmlDatabase(final Path file, final User user) {
return openDatabase(file, user, DatabaseType.XML);
}
/**
* Open database. A database can be opened only once (even across JVMs). Afterwards a singleton
* instance bound to the {@link File} is returned.
*
* @param file determines where the database is located
* @param user the user who interacts with the db
* @return {@link Database} instance.
* @throws SirixIOException if an I/O exception occurs
* @throws SirixUsageException if Sirix is not used properly
* @throws NullPointerException if {@code file} is {@code null}
*/
public static synchronized Database openJsonDatabase(final Path file, final User user) {
return openDatabase(file, user, DatabaseType.JSON);
}
/**
* Open database. A database can be opened only once (even across JVMs). Afterwards a singleton
* instance bound to the {@link File} is returned.
*
* @param file determines where the database is located
* @return {@link Database} instance.
* @throws SirixIOException if an I/O exception occurs
* @throws SirixUsageException if Sirix is not used properly
* @throws NullPointerException if {@code file} is {@code null}
*/
public static synchronized Database openJsonDatabase(final Path file) {
return openDatabase(file, createAdminUser(), DatabaseType.JSON);
}
/**
* Creates a reference to an admin user. Each call to this method will return a new user.
*
* @return A new admin user.
*/
private static User createAdminUser() {
return new User("admin", UUID.randomUUID());
}
/**
* Open database. A database can be opened only once (even across JVMs). Afterwards a singleton
* instance bound to the {@link File} is returned.
*
* @param file determines where the database is located
* @return {@link Database} instance.
* @throws SirixIOException if an I/O exception occurs
* @throws SirixUsageException if Sirix is not used properly
* @throws NullPointerException if {@code file} is {@code null}
*/
public static synchronized Database openXmlDatabase(final Path file) {
return openDatabase(file, createAdminUser(), DatabaseType.XML);
}
private static , R extends NodeReadOnlyTrx & NodeCursor, W extends NodeTrx & NodeCursor> Database openDatabase(
final Path file, final User user, final DatabaseType databaseType) {
requireNonNull(file);
if (!Files.exists(file)) {
throw new SirixUsageException("DB could not be opened (since it was not created?) at location", file.toString());
}
final DatabaseConfiguration dbConfig = DatabaseConfiguration.deserialize(file);
if (dbConfig == null) {
throw new IllegalStateException("Configuration may not be null!");
}
return databaseType.createDatabase(dbConfig, user);
}
/**
* Determines if a database already exists.
*
* @param dbPath database path
* @return {@code true}, if database exists, {@code false} otherwise
*/
public static synchronized boolean existsDatabase(final Path dbPath) {
return Files.exists(dbPath) && DatabaseConfiguration.DatabasePaths.compareStructure(dbPath) == 0;
}
public static ConcurrentMap getBufferManager(Path databaseFile) {
return BUFFER_MANAGERS.computeIfAbsent(databaseFile, (unused) -> new ConcurrentHashMap<>());
}
}