You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@tomcat.apache.org by fh...@apache.org on 2009/12/18 19:12:51 UTC
svn commit: r892330 - in
/tomcat/trunk/modules/jdbc-pool/java/org/apache/tomcat/jdbc: naming/
naming/GenericNamingResourcesFactory.java pool/DataSourceFactory.java
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-unsubscribe@tomcat.apache.org
For additional commands, e-mail: dev-help@tomcat.apache.org