Author: fhanik Date: Fri Dec 18 18:12:50 2009 New Revision: 892330 URL: http://svn.apache.org/viewvc?rev=892330&view=rev Log: Add in support to link up the connection pool to a DataSource or XADataSource through JNDI
Added: tomcat/trunk/modules/jdbc-pool/java/org/apache/tomcat/jdbc/naming/ tomcat/trunk/modules/jdbc-pool/java/org/apache/tomcat/jdbc/naming/GenericNamingResourcesFactory.java (with props) Modified: tomcat/trunk/modules/jdbc-pool/java/org/apache/tomcat/jdbc/pool/DataSourceFactory.java Added: tomcat/trunk/modules/jdbc-pool/java/org/apache/tomcat/jdbc/naming/GenericNamingResourcesFactory.java URL: http://svn.apache.org/viewvc/tomcat/trunk/modules/jdbc-pool/java/org/apache/tomcat/jdbc/naming/GenericNamingResourcesFactory.java?rev=892330&view=auto ============================================================================== --- tomcat/trunk/modules/jdbc-pool/java/org/apache/tomcat/jdbc/naming/GenericNamingResourcesFactory.java (added) +++ tomcat/trunk/modules/jdbc-pool/java/org/apache/tomcat/jdbc/naming/GenericNamingResourcesFactory.java Fri Dec 18 18:12:50 2009 @@ -0,0 +1,218 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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 org.apache.tomcat.jdbc.naming; + +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.net.InetAddress; +import java.net.UnknownHostException; +import java.util.Enumeration; +import java.util.Hashtable; + +import javax.naming.Context; +import javax.naming.Name; +import javax.naming.RefAddr; +import javax.naming.Reference; +import javax.naming.spi.ObjectFactory; + +import org.apache.juli.logging.Log; +import org.apache.juli.logging.LogFactory; +/** + * Simple way of configuring generic resources by using reflection. + * Example usage: + * <pre><code> + * <Resource factory="org.apache.tomcat.jdbc.naming.GenericNamingResourcesFactory" + * name="jdbc/test" + * type="org.apache.derby.jdbc.ClientXADataSource" + * databaseName="sample" + * createDatabase="create" + * serverName="localhost" + * port="1527"/> + * </code></pre> + * + */ +public class GenericNamingResourcesFactory implements ObjectFactory { + private static final Log log = LogFactory.getLog(GenericNamingResourcesFactory.class); + @Override + public Object getObjectInstance(Object obj, Name name, Context nameCtx, Hashtable<?, ?> environment) throws Exception { + if ((obj == null) || !(obj instanceof Reference)) { + return null; + } + Reference ref = (Reference) obj; + Enumeration<RefAddr> refs = ref.getAll(); + + String type = ref.getClassName(); + Object o = Class.forName(type).newInstance(); + + while (refs.hasMoreElements()) { + RefAddr addr = refs.nextElement(); + String param = addr.getType(); + String value = null; + if (addr.getContent()!=null) { + value = addr.getContent().toString(); + } + if (setProperty(o, param, value,false)) { + + } else { + log.debug("Property not configured["+param+"]. No setter found on["+o+"]."); + } + } + return o; + } + + public static boolean setProperty(Object o, String name, String value,boolean invokeSetProperty) { + if (log.isDebugEnabled()) + log.debug("IntrospectionUtils: setProperty(" + + o.getClass() + " " + name + "=" + value + ")"); + + String setter = "set" + capitalize(name); + + try { + Method methods[] = o.getClass().getMethods(); + Method setPropertyMethodVoid = null; + Method setPropertyMethodBool = null; + + // First, the ideal case - a setFoo( String ) method + for (int i = 0; i < methods.length; i++) { + Class<?> paramT[] = methods[i].getParameterTypes(); + if (setter.equals(methods[i].getName()) && paramT.length == 1 + && "java.lang.String".equals(paramT[0].getName())) { + + methods[i].invoke(o, new Object[] { value }); + return true; + } + } + + // Try a setFoo ( int ) or ( boolean ) + for (int i = 0; i < methods.length; i++) { + boolean ok = true; + if (setter.equals(methods[i].getName()) + && methods[i].getParameterTypes().length == 1) { + + // match - find the type and invoke it + Class<?> paramType = methods[i].getParameterTypes()[0]; + Object params[] = new Object[1]; + + // Try a setFoo ( int ) + if ("java.lang.Integer".equals(paramType.getName()) + || "int".equals(paramType.getName())) { + try { + params[0] = new Integer(value); + } catch (NumberFormatException ex) { + ok = false; + } + // Try a setFoo ( long ) + }else if ("java.lang.Long".equals(paramType.getName()) + || "long".equals(paramType.getName())) { + try { + params[0] = new Long(value); + } catch (NumberFormatException ex) { + ok = false; + } + + // Try a setFoo ( boolean ) + } else if ("java.lang.Boolean".equals(paramType.getName()) + || "boolean".equals(paramType.getName())) { + params[0] = new Boolean(value); + + // Try a setFoo ( InetAddress ) + } else if ("java.net.InetAddress".equals(paramType + .getName())) { + try { + params[0] = InetAddress.getByName(value); + } catch (UnknownHostException exc) { + if (log.isDebugEnabled()) + log.debug("IntrospectionUtils: Unable to resolve host name:" + value); + ok = false; + } + + // Unknown type + } else { + if (log.isDebugEnabled()) + log.debug("IntrospectionUtils: Unknown type " + + paramType.getName()); + } + + if (ok) { + methods[i].invoke(o, params); + return true; + } + } + + // save "setProperty" for later + if ("setProperty".equals(methods[i].getName())) { + if (methods[i].getReturnType()==Boolean.TYPE){ + setPropertyMethodBool = methods[i]; + }else { + setPropertyMethodVoid = methods[i]; + } + + } + } + + // Ok, no setXXX found, try a setProperty("name", "value") + if (setPropertyMethodBool != null || setPropertyMethodVoid != null) { + Object params[] = new Object[2]; + params[0] = name; + params[1] = value; + if (setPropertyMethodBool != null) { + try { + return (Boolean) setPropertyMethodBool.invoke(o, params); + }catch (IllegalArgumentException biae) { + //the boolean method had the wrong + //parameter types. lets try the other + if (setPropertyMethodVoid!=null) { + setPropertyMethodVoid.invoke(o, params); + return true; + }else { + throw biae; + } + } + } else { + setPropertyMethodVoid.invoke(o, params); + return true; + } + } + + } catch (IllegalArgumentException ex2) { + log.warn("IAE " + o + " " + name + " " + value, ex2); + } catch (SecurityException ex1) { + if (log.isDebugEnabled()) + log.debug("IntrospectionUtils: SecurityException for " + + o.getClass() + " " + name + "=" + value + ")", ex1); + } catch (IllegalAccessException iae) { + if (log.isDebugEnabled()) + log.debug("IntrospectionUtils: IllegalAccessException for " + + o.getClass() + " " + name + "=" + value + ")", iae); + } catch (InvocationTargetException ie) { + if (log.isDebugEnabled()) + log.debug("IntrospectionUtils: InvocationTargetException for " + + o.getClass() + " " + name + "=" + value + ")", ie); + } + return false; + } + + public static String capitalize(String name) { + if (name == null || name.length() == 0) { + return name; + } + char chars[] = name.toCharArray(); + chars[0] = Character.toUpperCase(chars[0]); + return new String(chars); + } + +} Propchange: tomcat/trunk/modules/jdbc-pool/java/org/apache/tomcat/jdbc/naming/GenericNamingResourcesFactory.java ------------------------------------------------------------------------------ svn:eol-style = native Modified: tomcat/trunk/modules/jdbc-pool/java/org/apache/tomcat/jdbc/pool/DataSourceFactory.java URL: http://svn.apache.org/viewvc/tomcat/trunk/modules/jdbc-pool/java/org/apache/tomcat/jdbc/pool/DataSourceFactory.java?rev=892330&r1=892329&r2=892330&view=diff ============================================================================== --- tomcat/trunk/modules/jdbc-pool/java/org/apache/tomcat/jdbc/pool/DataSourceFactory.java (original) +++ tomcat/trunk/modules/jdbc-pool/java/org/apache/tomcat/jdbc/pool/DataSourceFactory.java Fri Dec 18 18:12:50 2009 @@ -24,7 +24,9 @@ import javax.management.ObjectName; 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; @@ -207,7 +209,7 @@ } } - return createDataSource(properties); + return createDataSource(properties,nameCtx); } public static PoolConfiguration parsePoolProperties(Properties properties) throws IOException{ @@ -434,7 +436,8 @@ value = properties.getProperty(PROP_DATASOURCE); if (value != null) { //this should never happen - log.error("Can't set dataSource property as a string, this must be a javax.sql.DataSource object."); + throw new IllegalArgumentException("Can't set dataSource property as a string, this must be a javax.sql.DataSource object."); + } value = properties.getProperty(PROP_DATASOURCE_JNDI); @@ -452,15 +455,40 @@ * @throws Exception if an error occurs creating the data source */ public static DataSource createDataSource(Properties properties) throws Exception { + return createDataSource(properties,null); + } + public static DataSource createDataSource(Properties properties,Context context) throws Exception { PoolConfiguration poolProperties = DataSourceFactory.parsePoolProperties(properties); + if (poolProperties.getDataSourceJNDI()!=null && poolProperties.getDataSource()==null) { + javax.sql.DataSource jndiDS = null; + try { + if (context!=null) { + jndiDS = (javax.sql.DataSource)context.lookup(poolProperties.getDataSourceJNDI()); + } else { + log.warn("dataSourceJNDI property is configued, but local JNDI context is null."); + } + } catch (NamingException e) { + log.debug("The name \""+poolProperties.getDataSourceJNDI()+"\" can not be found in the local context."); + } + if (jndiDS==null) { + try { + context = (Context) (new InitialContext()); + jndiDS = (javax.sql.DataSource)context.lookup(poolProperties.getDataSourceJNDI()); + } catch (NamingException e) { + log.warn("The name \""+poolProperties.getDataSourceJNDI()+"\" can not be found in the InitialContext."); + } + } + if (jndiDS!=null) { + poolProperties.setDataSource(jndiDS); + } + } org.apache.tomcat.jdbc.pool.DataSource dataSource = new org.apache.tomcat.jdbc.pool.DataSource(poolProperties); - - //initialize the pool itself + //initialise the pool itself dataSource.createPool(); // Return the configured DataSource instance return dataSource; } - + /** * <p>Parse properties from the string. Format of the string must be [propertyName=property;]*<p> * @param propText --------------------------------------------------------------------- To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org For additional commands, e-mail: dev-h...@tomcat.apache.org