/* * Copyright (c) 2003, PostgreSQL Global Development Group * See the LICENSE file in the project root for more information. */ package org.postgresql.osgi; import org.postgresql.ds.common.BaseDataSource; import org.postgresql.jdbc2.optional.ConnectionPool; import org.postgresql.jdbc2.optional.PoolingDataSource; import org.postgresql.jdbc2.optional.SimpleDataSource; import org.postgresql.util.GT; import org.postgresql.util.PSQLException; import org.postgresql.util.PSQLState; import org.postgresql.xa.PGXADataSource; import org.osgi.service.jdbc.DataSourceFactory; import java.sql.SQLException; import java.util.Map.Entry; import java.util.Properties; import javax.sql.ConnectionPoolDataSource; import javax.sql.DataSource; import javax.sql.XADataSource; /** * This factory service is designed to be used in OSGi Enterprise environments to create and * configure JDBC data-sources. */ public class PGDataSourceFactory implements DataSourceFactory { /** * A class that removes properties as they are used (without modifying the supplied initial * Properties) */ private static class SingleUseProperties extends Properties { private static final long serialVersionUID = 1L; public SingleUseProperties(Properties initialProperties) { super(); if (initialProperties != null) { putAll(initialProperties); } } @Override public String getProperty(String key) { String value = super.getProperty(key); remove(key); return value; } } private void configureBaseDataSource(BaseDataSource ds, Properties props) throws SQLException { if (props.containsKey(JDBC_URL)) { ds.setUrl(props.getProperty(JDBC_URL)); } if (props.containsKey(JDBC_SERVER_NAME)) { ds.setServerName(props.getProperty(JDBC_SERVER_NAME)); } if (props.containsKey(JDBC_PORT_NUMBER)) { ds.setPortNumber(Integer.parseInt(props.getProperty(JDBC_PORT_NUMBER))); } if (props.containsKey(JDBC_DATABASE_NAME)) { ds.setDatabaseName(props.getProperty(JDBC_DATABASE_NAME)); } if (props.containsKey(JDBC_USER)) { ds.setUser(props.getProperty(JDBC_USER)); } if (props.containsKey(JDBC_PASSWORD)) { ds.setPassword(props.getProperty(JDBC_PASSWORD)); } for (Entry<Object, Object> entry : props.entrySet()) { ds.setProperty((String) entry.getKey(), (String) entry.getValue()); } } public java.sql.Driver createDriver(Properties props) throws SQLException { if (props != null && !props.isEmpty()) { throw new PSQLException(GT.tr("Unsupported properties: {0}", props.stringPropertyNames()), PSQLState.INVALID_PARAMETER_VALUE); } return new org.postgresql.Driver(); } private DataSource createPoolingDataSource(Properties props) throws SQLException { PoolingDataSource dataSource = new PoolingDataSource(); if (props.containsKey(JDBC_INITIAL_POOL_SIZE)) { dataSource.setInitialConnections(Integer.parseInt(props.getProperty(JDBC_INITIAL_POOL_SIZE))); } if (props.containsKey(JDBC_MAX_POOL_SIZE)) { dataSource.setMaxConnections(Integer.parseInt(props.getProperty(JDBC_MAX_POOL_SIZE))); } if (props.containsKey(JDBC_DATASOURCE_NAME)) { dataSource.setDataSourceName(props.getProperty(JDBC_DATASOURCE_NAME)); } configureBaseDataSource(dataSource, props); return dataSource; } private DataSource createSimpleDataSource(Properties props) throws SQLException { SimpleDataSource dataSource = new SimpleDataSource(); configureBaseDataSource(dataSource, props); return dataSource; } /** * Will create and return either a {@link SimpleDataSource} or a {@link PoolingDataSource} * depending on the presence in the supplied properties of any pool-related property (eg.: {@code * JDBC_INITIAL_POOL_SIZE} or {@code JDBC_MAX_POOL_SIZE}) */ public DataSource createDataSource(Properties props) throws SQLException { props = new SingleUseProperties(props); if (props.containsKey(JDBC_INITIAL_POOL_SIZE) || props.containsKey(JDBC_MIN_POOL_SIZE) || props.containsKey(JDBC_MAX_POOL_SIZE) || props.containsKey(JDBC_MAX_IDLE_TIME) || props.containsKey(JDBC_MAX_STATEMENTS)) { return createPoolingDataSource(props); } else { return createSimpleDataSource(props); } } public ConnectionPoolDataSource createConnectionPoolDataSource(Properties props) throws SQLException { props = new SingleUseProperties(props); ConnectionPool dataSource = new ConnectionPool(); configureBaseDataSource(dataSource, props); return dataSource; } public XADataSource createXADataSource(Properties props) throws SQLException { props = new SingleUseProperties(props); PGXADataSource dataSource = new PGXADataSource(); configureBaseDataSource(dataSource, props); return dataSource; } }