Use setters instead of direct property access in datasource initialisation
parent
fc03aeadb7
commit
1b261c7844
|
@ -1,6 +1,7 @@
|
|||
package net.openesb.standalone.naming.jndi.ds.tomcat;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.Method;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
|
@ -117,9 +118,6 @@ public class TomcatDataSourcePoolFactory implements DataSourcePoolFactory {
|
|||
throw ex;
|
||||
}
|
||||
|
||||
/*Return Fields declared in a class and its ancesters */
|
||||
Map<String, Field> dsFields = this.getAllFields(dsClass);
|
||||
|
||||
/*
|
||||
* Create datasource instance.
|
||||
*
|
||||
|
@ -139,65 +137,10 @@ public class TomcatDataSourcePoolFactory implements DataSourcePoolFactory {
|
|||
throw ex;
|
||||
}
|
||||
|
||||
/* Use java reflexion to set up Native Datasource declared in the context */
|
||||
Set<String> dspSet = datasourceMap.keySet();
|
||||
Iterator<String> keys = dspSet.iterator();
|
||||
while (keys.hasNext()) {
|
||||
String fieldName = keys.next();
|
||||
Field field = dsFields.get(fieldName);
|
||||
if (null == field) {
|
||||
LOG.log(Level.WARNING, I18NBundle.getBundle().getMessage(
|
||||
LocalStringKeys.DS_DATASOURCE_PROPERTY_NOT_FOUND, fieldName, dspProperties.getDbConnectorName(), dsName));
|
||||
} else {
|
||||
boolean accessible = field.isAccessible();
|
||||
field.setAccessible(true);
|
||||
setAllProperties(nativeDS, datasourceMap, "DS_DATASOURCE_");
|
||||
|
||||
String fieldValue = datasourceMap.get(fieldName);
|
||||
|
||||
if (LOG.isLoggable(Level.FINE)) {
|
||||
LOG.log(Level.FINE, I18NBundle.getBundle().getMessage(
|
||||
LocalStringKeys.DS_DATASOURCE_PROPERTY_SET, fieldName, fieldValue, dspProperties.getDbConnectorName()));
|
||||
}
|
||||
|
||||
try {
|
||||
if (field.getType().equals(byte.class)) {
|
||||
field.set(nativeDS, Byte.parseByte(fieldValue));
|
||||
} else if (field.getType().equals(boolean.class)) {
|
||||
field.set(nativeDS, Boolean.parseBoolean(fieldValue));
|
||||
} else if (field.getType().equals(char.class)) {
|
||||
field.set(nativeDS, fieldValue.charAt(0));
|
||||
} else if (field.getType().equals(short.class)) {
|
||||
field.set(nativeDS, Short.parseShort(fieldValue));
|
||||
} else if (field.getType().equals(int.class)) {
|
||||
field.set(nativeDS, Integer.parseInt(fieldValue));
|
||||
} else if (field.getType().equals(long.class)) {
|
||||
field.set(nativeDS, Long.parseLong(fieldValue));
|
||||
} else if (field.getType().equals(float.class)) {
|
||||
field.set(nativeDS, Float.parseFloat(fieldValue));
|
||||
} else if (field.getType().equals(double.class)) {
|
||||
field.set(nativeDS, Double.parseDouble(fieldValue));
|
||||
} else if (field.getType().equals(String.class)) {
|
||||
field.set(nativeDS, fieldValue);
|
||||
} else {
|
||||
LOG.log(Level.WARNING, I18NBundle.getBundle().getMessage(
|
||||
LocalStringKeys.DS_DATASOURCE_PROPERTY_NOT_SET, fieldName, field.getType(), dspProperties.getDbConnectorName()));
|
||||
}
|
||||
} catch (IllegalArgumentException ex) {
|
||||
LOG.log(Level.SEVERE, I18NBundle.getBundle().getMessage(
|
||||
LocalStringKeys.DS_DATASOURCE_PROPERTY_INVALID_VALUE, fieldValue, fieldName));
|
||||
throw ex;
|
||||
} catch (IllegalAccessException ex) {
|
||||
LOG.log(Level.SEVERE, I18NBundle.getBundle().getMessage(
|
||||
LocalStringKeys.DS_DATASOURCE_PROPERTY_ACCESS, fieldName));
|
||||
throw ex;
|
||||
} finally {
|
||||
field.setAccessible(accessible);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Datasouce fields are set with data proterties found in the context
|
||||
* Now let's set the pool with the pool proterties found in the context
|
||||
/* Datasouce fields are set with data properties found in the context
|
||||
* Now let's set the pool with the pool properties found in the context
|
||||
* get the properties for the pool */
|
||||
if (LOG.isLoggable(Level.INFO)) {
|
||||
LOG.log(Level.INFO, I18NBundle.getBundle().getMessage(
|
||||
|
@ -218,68 +161,77 @@ public class TomcatDataSourcePoolFactory implements DataSourcePoolFactory {
|
|||
org.apache.tomcat.jdbc.pool.PoolProperties poolProperties
|
||||
= new org.apache.tomcat.jdbc.pool.PoolProperties();
|
||||
|
||||
Class poolPropertiesClass = poolProperties.getClass();
|
||||
Map<String, Field> poolPropertiesFields = this.getAllFields(poolPropertiesClass);
|
||||
/* Use java reflexion to set up pool configurationwith context properties
|
||||
*/
|
||||
Set<String> poolPropertiesSet = poolMap.keySet();
|
||||
keys = poolPropertiesSet.iterator();
|
||||
setAllProperties(poolProperties, poolMap, "DS_POOL_");
|
||||
|
||||
while (keys.hasNext()) {
|
||||
|
||||
String fieldName = keys.next();
|
||||
Field field = poolPropertiesFields.get(fieldName);
|
||||
if (null == field) {
|
||||
LOG.log(Level.WARNING, I18NBundle.getBundle().getMessage(
|
||||
LocalStringKeys.DS_POOL_PROPERTY_NOT_FOUND, fieldName, dspProperties.getDbConnectorName(), dsName));
|
||||
} else {
|
||||
boolean accessible = field.isAccessible();
|
||||
field.setAccessible(true);
|
||||
|
||||
String fieldValue = poolMap.get(fieldName);
|
||||
try {
|
||||
if (field.getType().equals(byte.class)) {
|
||||
field.set(poolProperties, Byte.parseByte(fieldValue));
|
||||
} else if (field.getType().equals(boolean.class)) {
|
||||
field.set(poolProperties, Boolean.parseBoolean(fieldValue));
|
||||
} else if (field.getType().equals(char.class)) {
|
||||
field.set(poolProperties, fieldValue.charAt(0));
|
||||
} else if (field.getType().equals(short.class)) {
|
||||
field.set(poolProperties, Short.parseShort(fieldValue));
|
||||
} else if (field.getType().equals(int.class)) {
|
||||
field.set(poolProperties, Integer.parseInt(fieldValue));
|
||||
} else if (field.getType().equals(long.class)) {
|
||||
field.set(poolProperties, Long.parseLong(fieldValue));
|
||||
} else if (field.getType().equals(float.class)) {
|
||||
field.set(poolProperties, Float.parseFloat(fieldValue));
|
||||
} else if (field.getType().equals(double.class)) {
|
||||
field.set(poolProperties, Double.parseDouble(fieldValue));
|
||||
} else if (field.getType().equals(String.class)) {
|
||||
field.set(poolProperties, fieldValue);
|
||||
} else {
|
||||
LOG.log(Level.WARNING, I18NBundle.getBundle().getMessage(
|
||||
LocalStringKeys.DS_POOL_PROPERTY_NOT_SET, fieldName, field.getType(), dspProperties.getDbConnectorName()));
|
||||
}
|
||||
} catch (IllegalArgumentException ex) {
|
||||
LOG.log(Level.SEVERE, I18NBundle.getBundle().getMessage(
|
||||
LocalStringKeys.DS_POOL_PROPERTY_INVALID_VALUE, fieldValue, fieldName));
|
||||
throw ex;
|
||||
} catch (IllegalAccessException ex) {
|
||||
LOG.log(Level.SEVERE, I18NBundle.getBundle().getMessage(
|
||||
LocalStringKeys.DS_POOL_PROPERTY_ACCESS, fieldName));
|
||||
throw ex;
|
||||
} finally {
|
||||
field.setAccessible(accessible);
|
||||
}
|
||||
}
|
||||
}
|
||||
// set the pool and get a Poolled Datasource
|
||||
// set the pool and get a Pooled Datasource
|
||||
poolProperties.setDataSource(nativeDS);
|
||||
poolProperties.setJmxEnabled(true);
|
||||
|
||||
return poolProperties;
|
||||
}
|
||||
|
||||
/**
|
||||
* Use java reflection to call setters on an object
|
||||
*/
|
||||
private void setAllProperties(Object obj, Map<String, String> props, String errPrefix)
|
||||
throws IllegalAccessException, IllegalArgumentException, InvocationTargetException
|
||||
{
|
||||
Class cl = obj.getClass();
|
||||
Map<String, Method> setters = getAllSetters(cl);
|
||||
Set<String> propSet = props.keySet();
|
||||
Iterator<String> keys = propSet.iterator();
|
||||
while (keys.hasNext()) {
|
||||
String fieldName = keys.next();
|
||||
Method m = setters.get(fieldName.toLowerCase());
|
||||
if (null == m) {
|
||||
LOG.log(Level.WARNING, I18NBundle.getBundle().getMessage(
|
||||
errPrefix+"PROPERTY_NOT_FOUND", fieldName, cl.getName()));
|
||||
continue;
|
||||
}
|
||||
String fieldValue = props.get(fieldName);
|
||||
Class<?>[] paramTypes = m.getParameterTypes();
|
||||
if (paramTypes.length != 1) {
|
||||
LOG.log(Level.WARNING, "Method is not a setter or has more than 1 argument: "+cl.getName()+"."+m.getName());
|
||||
continue;
|
||||
}
|
||||
Class<?> t = paramTypes[0];
|
||||
try {
|
||||
if (t.equals(byte.class)) {
|
||||
m.invoke(obj, Byte.parseByte(fieldValue));
|
||||
} else if (t.equals(boolean.class)) {
|
||||
m.invoke(obj, Boolean.parseBoolean(fieldValue));
|
||||
} else if (t.equals(char.class)) {
|
||||
m.invoke(obj, fieldValue.charAt(0));
|
||||
} else if (t.equals(short.class)) {
|
||||
m.invoke(obj, Short.parseShort(fieldValue));
|
||||
} else if (t.equals(int.class)) {
|
||||
m.invoke(obj, Integer.parseInt(fieldValue));
|
||||
} else if (t.equals(long.class)) {
|
||||
m.invoke(obj, Long.parseLong(fieldValue));
|
||||
} else if (t.equals(float.class)) {
|
||||
m.invoke(obj, Float.parseFloat(fieldValue));
|
||||
} else if (t.equals(double.class)) {
|
||||
m.invoke(obj, Double.parseDouble(fieldValue));
|
||||
} else if (t.equals(String.class)) {
|
||||
m.invoke(obj, fieldValue);
|
||||
} else {
|
||||
LOG.log(Level.WARNING, I18NBundle.getBundle().getMessage(
|
||||
errPrefix+"PROPERTY_NOT_SET", fieldName, t, cl.getName()));
|
||||
}
|
||||
} catch (InvocationTargetException ex) {
|
||||
throw ex;
|
||||
} catch (IllegalArgumentException ex) {
|
||||
LOG.log(Level.SEVERE, I18NBundle.getBundle().getMessage(
|
||||
errPrefix+"PROPERTY_INVALID_VALUE", fieldValue, fieldName));
|
||||
throw ex;
|
||||
} catch (IllegalAccessException ex) {
|
||||
LOG.log(Level.SEVERE, I18NBundle.getBundle().getMessage(
|
||||
errPrefix+"PROPERTY_ACCESS", fieldName));
|
||||
throw ex;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* List to Map is an internal methode used to convert a List<Property> to a Map.
|
||||
* Map will be use to set the DataSource and the Pool
|
||||
*/
|
||||
|
@ -306,24 +258,17 @@ public class TomcatDataSourcePoolFactory implements DataSourcePoolFactory {
|
|||
return outputMap;
|
||||
}
|
||||
|
||||
/* getAll field is used to get all the fields declared in a class + its ancesters
|
||||
* getDeclaredField just returns the field declared at the class level and not
|
||||
* at the ancester levels. The retured map contains key-values pairs with Field name and Field object
|
||||
/* getAllSetters is used to get all the setters declared in a class and its ancestors.
|
||||
* The retured map contains key-values pairs with lowercased field names and Method objects.
|
||||
*/
|
||||
private Map<String, Field> getAllFields(Class<?> type) {
|
||||
List<Field> listFields = new ArrayList<Field>();
|
||||
for (Class<?> c = type; c
|
||||
!= Object.class; c = c.getSuperclass()) {
|
||||
listFields.addAll(Arrays.asList(c.getDeclaredFields()));
|
||||
private Map<String, Method> getAllSetters(Class<?> type) {
|
||||
Map<String, Method> mapSetters = new HashMap<String, Method>();
|
||||
Method[] methods = type.getMethods();
|
||||
for (int i = 0; i < methods.length; i++) {
|
||||
String name = methods[i].getName().toLowerCase();
|
||||
if (name.startsWith("set"))
|
||||
mapSetters.put(name.substring(3), methods[i]);
|
||||
}
|
||||
Map<String, Field> mapFields = new HashMap<String, Field>();
|
||||
Iterator<Field> fieldIterator = listFields.iterator();
|
||||
|
||||
while (fieldIterator.hasNext()) {
|
||||
Field field = fieldIterator.next();
|
||||
String fieldName = field.getName();
|
||||
mapFields.put(fieldName, field);
|
||||
}
|
||||
return mapFields;
|
||||
return mapSetters;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -82,7 +82,7 @@ DS_DATASOURCE_PROPERTY_INVALID_VALUE= OESE-1510: Value {\u00d8} for {1} is not a
|
|||
DS_DATASOURCE_PROPERTY_ACCESS = OESE-1511: Can not set value for field {0}
|
||||
DS_UNABLE_TO_CREATE_MBEAN = OESE-1512: An error occurs while registering MBean for datasource {0}
|
||||
DS_POOL_CONFIGURATION = OESE-1513: Trying to configure pool for datasource {0}
|
||||
DS_POOL_PROPERTY_NOT_FOUND = OESE-1514: Pool property {0} not found for datasource {1} (in {2})
|
||||
DS_POOL_PROPERTY_NOT_FOUND = OESE-1514: Pool property {0} not found in {1} for datasource
|
||||
DS_POOL_PROPERTY_SET = OESE-1515: Trying to set property {0} with value {1} for {2}
|
||||
DS_POOL_PROPERTY_NOT_SET = OESE-1516: Property {\u00d8} of type {1} can not be set for {2}
|
||||
DS_POOL_PROPERTY_INVALID_VALUE = OESE-1517: Value {\u00d8} for {1} is not a valid value
|
||||
|
|
Loading…
Reference in New Issue