com.ziclix.python.sql.connect.Connectx Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of jython-slim Show documentation
Show all versions of jython-slim Show documentation
Jython is an implementation of the high-level, dynamic, object-oriented
language Python written in 100% Pure Java, and seamlessly integrated with
the Java platform. It thus allows you to run Python on any Java platform.
/*
* Jython Database Specification API 2.0
*
*
* Copyright (c) 2001 brian zimmer
*
*/
package com.ziclix.python.sql.connect;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.sql.Connection;
import java.sql.SQLException;
import javax.sql.ConnectionPoolDataSource;
import javax.sql.DataSource;
import org.python.core.Py;
import org.python.core.PyObject;
import org.python.core.PyString;
import org.python.core.Untraversable;
import com.ziclix.python.sql.PyConnection;
import com.ziclix.python.sql.zxJDBC;
import com.ziclix.python.sql.util.PyArgParser;
/**
* Connect using through a javax.sql.DataSource or javax.sql.ConnectionPooledDataSource.
*
* @author brian zimmer
*/
@Untraversable
public class Connectx extends PyObject {
private static final String SET = "set";
private static final PyString _doc =
new PyString("establish a connection through a javax.sql.DataSource or "
+ "javax.sql.ConnectionPooledDataSource");
@Override
public PyObject __findattr_ex__(String name) {
if ("__doc__".equals(name)) {
return _doc;
}
return super.__findattr_ex__(name);
}
/**
* Construct a javax.sql.DataSource or javax.sql.ConnectionPooledDataSource
*/
@Override
public PyObject __call__(PyObject[] args, String[] keywords) {
Connection c = null;
PyConnection pc = null;
Object datasource = null;
PyArgParser parser = new PyArgParser(args, keywords);
try {
String klass = (String) parser.arg(0).__tojava__(String.class);
datasource = Class.forName(klass).getDeclaredConstructor().newInstance();
} catch (Exception e) {
throw zxJDBC.makeException(zxJDBC.DatabaseError, "unable to instantiate datasource");
}
String[] kws = parser.kws();
for (int i = 0; i < kws.length; i++) {
String methodName = kws[i];
if (methodName == null) {
continue;
}
Object value = parser.kw(kws[i]).__tojava__(Object.class);
if (methodName.length() > SET.length()) {
if (!SET.equals(methodName.substring(0, SET.length()))) {
// prepend "set"
invoke(datasource, SET + methodName.substring(0, 1).toUpperCase()
+ methodName.substring(1), value);
} else {
// starts with "set" so just pass it on
invoke(datasource, methodName, value);
}
} else {
// shorter than "set" so it can't be a full method name
invoke(datasource,
SET + methodName.substring(0, 1).toUpperCase() + methodName.substring(1),
value);
}
}
try {
if (datasource instanceof ConnectionPoolDataSource) {
c = ((ConnectionPoolDataSource) datasource).getPooledConnection().getConnection();
} else if (datasource instanceof DataSource) {
c = ((DataSource) datasource).getConnection();
}
} catch (SQLException e) {
throw zxJDBC.makeException(zxJDBC.DatabaseError, e);
}
try {
if (c == null || c.isClosed()) {
throw zxJDBC.makeException(zxJDBC.DatabaseError, "unable to establish connection");
}
pc = new PyConnection(c);
} catch (SQLException e) {
throw zxJDBC.makeException(zxJDBC.DatabaseError, e);
}
return pc;
}
@Override
public String toString() {
return String.format("", Py.id(this));
}
/**
* Method invoke
*
* @param src
* @param methodName
* @param value
*/
protected void invoke(Object src, String methodName, Object value) {
Method method = null;
StringBuffer exceptionMsg = new StringBuffer("method [");
exceptionMsg.append(methodName).append("] using arg type [");
exceptionMsg.append(value.getClass()).append("], value [");
exceptionMsg.append(value.toString()).append("]");
try {
method = getMethod(src.getClass(), methodName, value.getClass());
if (method == null) {
throw zxJDBC.makeException("no such " + exceptionMsg);
}
method.invoke(src, new Object[]{value});
} catch (IllegalAccessException e) {
throw zxJDBC.makeException("illegal access for " + exceptionMsg);
} catch (InvocationTargetException e) {
throw zxJDBC.makeException("invocation target exception for " + exceptionMsg);
}
return;
}
/**
* Try to find the method by the given name. If failing that, see if the valueClass
* is perhaps a primitive and attempt to recurse using the primitive type. Failing
* that return null.
*/
protected Method getMethod(Class> srcClass, String methodName, Class> valueClass) {
Method method = null;
try {
method = srcClass.getMethod(methodName, new Class[]{valueClass});
} catch (NoSuchMethodException e) {
Class> primitive = null;
try {
Field f = valueClass.getField("TYPE");
primitive = (Class>) f.get(valueClass);
} catch (NoSuchFieldException ex) {
} catch (IllegalAccessException ex) {
} catch (ClassCastException ex) {
}
if (primitive != null && primitive.isPrimitive()) {
return getMethod(srcClass, methodName, primitive);
}
}
return method;
}
}