Add a JNDI factory to create datasources for Tomcat users.

pull/77/head
Brett Wooldridge 11 years ago
parent cfda5e022c
commit 9a446d62fb

@ -159,6 +159,8 @@
<Import-Package> <Import-Package>
javassist.*, javassist.*,
javax.management, javax.management,
javax.naming,
javax.naming.spi,
javax.sql, javax.sql,
javax.sql.rowset, javax.sql.rowset,
javax.sql.rowset.serial, javax.sql.rowset.serial,

@ -59,6 +59,7 @@ public class HikariConfig implements HikariConfigMBean
private String connectionInitSql; private String connectionInitSql;
private String connectionTestQuery; private String connectionTestQuery;
private String dataSourceClassName; private String dataSourceClassName;
private String dataSourceJndiName;
private String driverClassName; private String driverClassName;
private String jdbcUrl; private String jdbcUrl;
private String password; private String password;
@ -76,6 +77,7 @@ public class HikariConfig implements HikariConfigMBean
private Properties dataSourceProperties; private Properties dataSourceProperties;
private int transactionIsolation; private int transactionIsolation;
static static
{ {
JavassistProxyFactory.initialize(); JavassistProxyFactory.initialize();
@ -310,6 +312,16 @@ public class HikariConfig implements HikariConfigMBean
dataSourceProperties.put(propertyName, value); dataSourceProperties.put(propertyName, value);
} }
public String getDataSourceJNDI()
{
return this.dataSourceJndiName;
}
public void setDataSourceJNDI(String jndiDataSource)
{
this.dataSourceJndiName = jndiDataSource;
}
public Properties getDataSourceProperties() public Properties getDataSourceProperties()
{ {
return dataSourceProperties; return dataSourceProperties;

@ -0,0 +1,122 @@
/*
* Copyright (C) 2013,2014 Brett Wooldridge
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.zaxxer.hikari;
import java.util.Hashtable;
import java.util.Properties;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.Name;
import javax.naming.NamingException;
import javax.naming.RefAddr;
import javax.naming.Reference;
import javax.naming.spi.ObjectFactory;
import javax.sql.DataSource;
import com.zaxxer.hikari.pool.HikariPool;
import com.zaxxer.hikari.util.PropertyBeanSetter;
/**
* A JNDI factory that produces HikariDataSource instances.
*
* @author Brett Wooldridge
*/
public class HikariJNDIFactory implements ObjectFactory
{
@Override
public Object getObjectInstance(Object obj, Name name, Context nameCtx, Hashtable<?, ?> environment) throws Exception
{
// We only know how to deal with <code>javax.naming.Reference</code> that specify a class name of "javax.sql.DataSource"
if ((obj == null) || !(obj instanceof Reference))
{
return null;
}
Reference ref = (Reference) obj;
if (!"javax.sql.DataSource".equals(ref.getClassName()))
{
throw new NamingException(ref.getClassName() + " is not a valid class name/type for this JNDI factory.");
}
Properties properties = new Properties();
for (String propertyName : PropertyBeanSetter.getPropertyNames(HikariPool.class))
{
RefAddr ra = ref.get(propertyName);
if (ra != null)
{
String propertyValue = ra.getContent().toString();
properties.setProperty(propertyName, propertyValue);
}
}
return createDataSource(properties, nameCtx);
}
private DataSource createDataSource(Properties properties, Context context)
{
if (properties.getProperty("dataSourceJNDI") != null)
{
return lookupJndiDataSource(properties, context);
}
return new HikariDataSource(new HikariConfig(properties));
}
private DataSource lookupJndiDataSource(Properties properties, Context context)
{
DataSource jndiDS = null;
String jndiName = properties.getProperty("dataSourceJNDI");
try
{
if (context != null)
{
jndiDS = (DataSource) context.lookup(jndiName);
}
else
{
throw new RuntimeException("dataSourceJNDI property is configued, but local JNDI context is null.");
}
}
catch (NamingException e)
{
throw new RuntimeException("The name \"" + jndiName + "\" can not be found in the local context.");
}
if (jndiDS == null)
{
try
{
context = (Context) (new InitialContext());
jndiDS = (DataSource) context.lookup(jndiName);
}
catch (NamingException e)
{
throw new RuntimeException("The name \"" + jndiName + "\" can not be found in the InitialContext.");
}
}
if (jndiDS != null)
{
HikariConfig config = new HikariConfig(properties);
config.setDataSource(jndiDS);
return new HikariDataSource(config);
}
return null;
}
}

@ -16,10 +16,14 @@
package com.zaxxer.hikari.util; package com.zaxxer.hikari.util;
import java.beans.BeanInfo;
import java.beans.IntrospectionException; import java.beans.IntrospectionException;
import java.beans.Introspector;
import java.beans.PropertyDescriptor; import java.beans.PropertyDescriptor;
import java.lang.reflect.Method; import java.lang.reflect.Method;
import java.util.HashSet;
import java.util.Properties; import java.util.Properties;
import java.util.Set;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
@ -27,6 +31,7 @@ import org.slf4j.LoggerFactory;
import com.zaxxer.hikari.HikariConfig; import com.zaxxer.hikari.HikariConfig;
/** /**
* A class that reflectively sets bean properties on a target object.
* *
* @author Brett Wooldridge * @author Brett Wooldridge
*/ */
@ -58,6 +63,31 @@ public final class PropertyBeanSetter
} }
} }
/**
* Get the bean-style property names for the specified object.
*
* @param targetClass the target object
* @return a set of property names
*/
public static Set<String> getPropertyNames(Class<?> targetClass)
{
HashSet<String> set = new HashSet<String>();
try
{
BeanInfo info = Introspector.getBeanInfo(targetClass);
for (PropertyDescriptor descr : info.getPropertyDescriptors())
{
set.add(descr.getName());
}
return set;
}
catch (IntrospectionException e)
{
throw new RuntimeException(e);
}
}
private static void setProperty(Object target, String propName, Object propValue) private static void setProperty(Object target, String propName, Object propValue)
{ {
String capitalized = "set" + propName.substring(0, 1).toUpperCase() + propName.substring(1); String capitalized = "set" + propName.substring(0, 1).toUpperCase() + propName.substring(1);

@ -1,9 +1,30 @@
/*
* Copyright (C) 2013 Brett Wooldridge
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.zaxxer.hikari; package com.zaxxer.hikari;
import java.lang.reflect.Field; import java.lang.reflect.Field;
import com.zaxxer.hikari.pool.HikariPool; import com.zaxxer.hikari.pool.HikariPool;
/**
* Utility methods for testing.
*
* @author Brett Wooldridge
*/
public final class TestElf public final class TestElf
{ {
private TestElf() private TestElf()

Loading…
Cancel
Save