package co.codewizards.cloudstore.local;
import static co.codewizards.cloudstore.core.io.StreamUtil.*;
import static co.codewizards.cloudstore.core.oio.OioFileFactory.*;
import static co.codewizards.cloudstore.core.repo.local.LocalRepoManager.*;
import static co.codewizards.cloudstore.core.util.AssertUtil.*;
import static co.codewizards.cloudstore.core.util.StringUtil.*;
import java.io.InputStream;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.util.Map;
import java.util.Properties;
import java.util.UUID;
import javax.jdo.PersistenceManagerFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import co.codewizards.cloudstore.core.oio.File;
/**
* Factory creating JDBC connections to the repository's derby database.
* <p>
* <b>Important: This is for maintenance only!</b> Ordinary operations work with a {@link PersistenceManagerFactory}
* which is managed by {@link LocalRepoManagerImpl}.
* @author Marco หงุ่ยตระกูล-Schulze - marco at codewizards dot co
*/
public class JdbcConnectionFactory {
private static final Logger logger = LoggerFactory.getLogger(JdbcConnectionFactory.class);
private final File localRoot;
private String connectionURL;
private String connectionDriverName;
private String connectionUserName;
private String connectionPassword;
public JdbcConnectionFactory(final File localRoot) {
this.localRoot = assertNotNull(localRoot, "localRoot");
if (!localRoot.isDirectory())
throw new IllegalArgumentException("The given localRoot is not an existing directory: " + localRoot.getAbsolutePath());
initProperties();
initDriverClass();
}
private UUID readRepositoryIdFromRepositoryPropertiesFile() {
final File repositoryPropertiesFile = createFile(getMetaDir(), REPOSITORY_PROPERTIES_FILE_NAME);
try {
final Properties repositoryProperties = new Properties();
try (InputStream in = castStream(repositoryPropertiesFile.createInputStream())) {
repositoryProperties.load(in);
}
final String repositoryIdStr = repositoryProperties.getProperty(PROP_REPOSITORY_ID);
if (isEmpty(repositoryIdStr))
throw new IllegalStateException("repositoryProperties.getProperty(PROP_REPOSITORY_ID) is empty!");
final UUID repositoryId = UUID.fromString(repositoryIdStr);
return repositoryId;
} catch (Exception x) {
throw new RuntimeException("Reading readRepositoryId from '" + repositoryPropertiesFile.getAbsolutePath() + "' failed: " + x, x);
}
}
private void initProperties() {
UUID repositoryId = readRepositoryIdFromRepositoryPropertiesFile();
Map<String, String> persistenceProperties = new PersistencePropertiesProvider(repositoryId, localRoot).getPersistenceProperties();
connectionDriverName = persistenceProperties.get(PersistencePropertiesEnum.CONNECTION_DRIVER_NAME.key);
connectionURL = persistenceProperties.get(PersistencePropertiesEnum.CONNECTION_URL.key);
connectionUserName = persistenceProperties.get(PersistencePropertiesEnum.CONNECTION_USER_NAME.key);
connectionPassword = persistenceProperties.get(PersistencePropertiesEnum.CONNECTION_PASSWORD.key);
};
protected File getMetaDir() {
return createFile(localRoot, META_DIR_NAME);
}
private void initDriverClass() {
if (isEmpty(connectionDriverName))
return;
try {
Class.forName(connectionDriverName);
} catch (Throwable e) { // Might theoretically be a link error (i.e. a sub-class of Error instead of Exception) => catch Throwable
logger.warn("initDriverClass" + e, e);
}
}
public Connection createConnection() throws SQLException {
if (isEmpty(connectionUserName) && isEmpty(connectionPassword))
return DriverManager.getConnection(connectionURL);
else
return DriverManager.getConnection(connectionURL, connectionUserName, connectionPassword);
}
}