Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- import lombok.*;
- import lombok.experimental.Delegate;
- import lombok.experimental.FieldDefaults;
- import lombok.extern.log4j.Log4j2;
- import java.io.FileInputStream;
- import java.io.IOException;
- import java.sql.Connection;
- import java.sql.DriverManager;
- import java.sql.SQLException;
- import java.sql.Statement;
- import java.util.Properties;
- import java.util.Queue;
- import java.util.concurrent.ArrayBlockingQueue;
- import java.util.concurrent.locks.Lock;
- import java.util.concurrent.locks.ReentrantLock;
- @Log4j2
- @FieldDefaults(level = AccessLevel.PRIVATE)
- public class ConnectionPool {
- static final String PATH_TO_PROPS = "src/main/resources/dbprops.xml";
- static final String DEFAULT_URL = "jdbc:sqlite:database.db";
- static final int DEFAULT_MAX_CONNECTIONS = 10;
- static final String DEFAULT_USER = "root";
- static final String DEFAULT_PASSWORD = "root";
- static final boolean DEFAULT_IS_TEST = true;
- static final ConnectionPool connectionPool;
- final Lock lock = new ReentrantLock();
- final Queue<Connection> availableConnections;
- final Queue<Connection> usedConnections;
- @Getter
- int maxConnections;
- @Getter
- String driverUrl;
- @Getter
- String password;
- @Getter
- String user;
- @Getter
- boolean isTest;
- static {
- connectionPool = new ConnectionPool();
- }
- private ConnectionPool() {
- Properties properties = new Properties();
- try {
- FileInputStream fileInputStream = new FileInputStream(PATH_TO_PROPS);
- properties.loadFromXML(fileInputStream);
- } catch (IOException e) {
- log.error("Cannot find config file, use default", e);
- driverUrl = DEFAULT_URL;
- maxConnections = DEFAULT_MAX_CONNECTIONS;
- user = DEFAULT_USER;
- password = DEFAULT_PASSWORD;
- isTest = DEFAULT_IS_TEST;
- } finally {
- if (driverUrl == null) {
- driverUrl = properties.getProperty("db-url", DEFAULT_URL);
- maxConnections = Integer.valueOf(properties.getProperty("max-connections",
- String.valueOf(DEFAULT_MAX_CONNECTIONS)));
- user = properties.getProperty("user", DEFAULT_USER);
- password = properties.getProperty("password", DEFAULT_PASSWORD);
- isTest = Boolean.valueOf(properties.getProperty("test", String.valueOf(DEFAULT_IS_TEST)));
- }
- }
- availableConnections = new ArrayBlockingQueue<>(maxConnections);
- usedConnections = new ArrayBlockingQueue<>(maxConnections);
- }
- public static ConnectionPool getConnectionPool() {
- return connectionPool;
- }
- public Connection getConnection() {
- // 1:
- // May be this is redundant, but I think that it's semantically correct.
- // I just want let the others see only consistent object.
- lock.lock();
- if (availableConnections.size() + usedConnections.size() < maxConnections && availableConnections.size() == 0) {
- try {
- PooledConnection pooledConnection = new PooledConnection(DriverManager.getConnection(driverUrl, user, password));
- availableConnections.offer(pooledConnection);
- } catch (SQLException e) {
- log.error("Connection was not created.", e);
- }
- }
- Connection connection = availableConnections.poll();
- if (connection != null) {
- usedConnections.offer(connection);
- }
- lock.unlock();
- return connection;
- }
- public int connectionsAvailable() {
- return availableConnections.size();
- }
- @AllArgsConstructor
- @FieldDefaults(level = AccessLevel.PRIVATE)
- @EqualsAndHashCode
- private class PooledConnection implements Connection {
- @Delegate(excludes = {AutoCloseable.class})
- Connection connection;
- @Override
- public void close() {
- try {
- // Goto 1;
- lock.lock();
- usedConnections.remove(this);
- // You know da way.
- availableConnections.offer(this);
- lock.unlock();
- } catch (SQLException e) {
- log.error("Connection was not created.", e);
- }
- log.info("Connection: [" + connection + "] were returned.");
- }
- }
- }
Add Comment
Please, Sign In to add comment