exclusion from guessing for non-annotation member types

support for PyClass
support for name pattern for INIT
minor cleanup
master
Abhinav Sarkar 2009-10-31 00:16:42 +05:30
parent cc159354ce
commit f4c4ef73bb
10 changed files with 946 additions and 909 deletions

View File

@ -3,6 +3,7 @@
<classpathentry kind="src" path="src/main/java"/> <classpathentry kind="src" path="src/main/java"/>
<classpathentry kind="src" path="src/example/java"/> <classpathentry kind="src" path="src/example/java"/>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/> <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
<classpathentry kind="var" path="JYTHON_HOME/jython.jar" sourcepath="/JYTHON_HOME/Doc/javadoc"/> <classpathentry kind="var" path="JYTHON_HOME/jython.jar" sourcepath="/JYTHON_HOME/src"/>
<classpathentry kind="con" path="org.eclipse.jdt.junit.JUNIT_CONTAINER/4"/>
<classpathentry kind="output" path="bin"/> <classpathentry kind="output" path="bin"/>
</classpath> </classpath>

View File

@ -1,17 +1,23 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<projectDescription> <projectDescription>
<name>jywrapper</name> <name>jywrapper</name>
<comment></comment> <comment></comment>
<projects> <projects>
</projects> </projects>
<buildSpec> <buildSpec>
<buildCommand> <buildCommand>
<name>org.eclipse.jdt.core.javabuilder</name> <name>org.python.pydev.PyDevBuilder</name>
<arguments> <arguments>
</arguments> </arguments>
</buildCommand> </buildCommand>
</buildSpec> <buildCommand>
<natures> <name>org.eclipse.jdt.core.javabuilder</name>
<nature>org.eclipse.jdt.core.javanature</nature> <arguments>
</natures> </arguments>
</projectDescription> </buildCommand>
</buildSpec>
<natures>
<nature>org.eclipse.jdt.core.javanature</nature>
<nature>org.python.pydev.pythonNature</nature>
</natures>
</projectDescription>

View File

@ -1,89 +1,92 @@
package net.abhinavsarkar.jywrapper; package net.abhinavsarkar.jywrapper;
import static net.abhinavsarkar.jywrapper.Messages._; import static net.abhinavsarkar.jywrapper.Messages._;
import net.abhinavsarkar.jywrapper.annotation.Wraps; import net.abhinavsarkar.jywrapper.annotation.Wraps;
import net.abhinavsarkar.jywrapper.exception.PythonImportNotFoundException; import net.abhinavsarkar.jywrapper.exception.PythonImportNotFoundException;
import org.python.core.PyFunction; import org.python.core.PyClass;
import org.python.core.PyModule; import org.python.core.PyFunction;
import org.python.core.PyObject; import org.python.core.PyModule;
import org.python.core.PyType; import org.python.core.PyObject;
import org.python.core.PyType;
/**
* @author Abhinav Sarkar <abhinav@abhinavsarkar.net> /**
* * @author Abhinav Sarkar <abhinav@abhinavsarkar.net>
* @param <T> The type of the java class to wrap the Python class/module with. *
*/ * @param <T> The type of the java class to wrap the Python class/module with.
public final class JyWrapper { */
public final class JyWrapper {
private JyWrapper() {
} private JyWrapper() {
}
public static <T> T wrap(final Class<T> javaClass) {
final Wraps annotation = javaClass.getAnnotation(Wraps.class); public static <T> T wrap(final Class<T> javaClass) {
if (annotation == null) { final Wraps annotation = javaClass.getAnnotation(Wraps.class);
throw new PythonImportNotFoundException(_("JyWrapper.7", javaClass)); //$NON-NLS-1$ if (annotation == null) {
} throw new PythonImportNotFoundException(_("JyWrapper.7", javaClass)); //$NON-NLS-1$
}
return wrap(javaClass, annotation.value());
} return wrap(javaClass, annotation.value());
}
/**
* @param pyImportName The full import name of the Python class/module /**
* to wrap. * @param pyImportName The full import name of the Python class/module
* @return An instance of {@link UninitedPyObjectWrapper}, ready to be * to wrap.
* initialized. * @return An instance of {@link UninitedPyObjectWrapper}, ready to be
* @throws IllegalStateException Thrown if the java Class to be used to * initialized.
* wrap the Python module/class, has not been supplied by earlier * @throws IllegalStateException Thrown if the java Class to be used to
* calling {@link JyWrapper#with(Class)}. * wrap the Python module/class, has not been supplied by earlier
* @throws IllegalArgumentException Thrown if the pyImportName parameter * calling {@link JyWrapper#with(Class)}.
* is null. * @throws IllegalArgumentException Thrown if the pyImportName parameter
*/ * is null.
public static <T> T wrap(final Class<T> javaClass, final String pyImportName) { */
if (javaClass == null) { public static <T> T wrap(final Class<T> javaClass, final String pyImportName) {
throw new IllegalStateException(_("JyWrapper.6", "javaClass")); //$NON-NLS-1$ //$NON-NLS-2$ if (javaClass == null) {
} throw new IllegalStateException(_("JyWrapper.6", "javaClass")); //$NON-NLS-1$ //$NON-NLS-2$
if (pyImportName == null) { }
throw new IllegalArgumentException(_("JyWrapper.6", "pyImportName")); //$NON-NLS-1$ //$NON-NLS-2$ if (pyImportName == null) {
} throw new IllegalArgumentException(_("JyWrapper.6", "pyImportName")); //$NON-NLS-1$ //$NON-NLS-2$
}
final PyObject pyImport = PyImportLoader.loadPyImport(pyImportName);
if (!(pyImport instanceof PyType || pyImport instanceof PyModule)) { final PyObject pyImport = PyImportLoader.loadPyImport(pyImportName);
throw new IllegalArgumentException(_("JyWrapper.5", pyImportName)); //$NON-NLS-1$ if (!(pyImport instanceof PyType
} || pyImport instanceof PyModule
return Util.py2Java(pyImport, javaClass); || pyImport instanceof PyClass)) {
} throw new IllegalArgumentException(_("JyWrapper.5", pyImportName)); //$NON-NLS-1$
}
/** return Util.py2Java(pyImport, javaClass);
* @param <T> The return type of the {@link PyCallable} instance. }
* @param pyImportName The full import name of the Python function to wrap.
* @param returnType The class of the return type. /**
* @return An instance of {@link PyCallable} which wraps the * @param <T> The return type of the {@link PyCallable} instance.
* Python function given in parameter. * @param pyImportName The full import name of the Python function to wrap.
* @throws IllegalArgumentException Thrown if the any of the parameters * @param returnType The class of the return type.
* supplied are null or if the pyImportName parameter supplied does not * @return An instance of {@link PyCallable} which wraps the
* correspond to a Python function. * Python function given in parameter.
*/ * @throws IllegalArgumentException Thrown if the any of the parameters
public static <T> PyCallable<T> wrapPyFunction( * supplied are null or if the pyImportName parameter supplied does not
final String pyImportName, final Class<T> returnType) { * correspond to a Python function.
if (pyImportName == null) { */
throw new IllegalArgumentException(_("JyWrapper.6", "pyImportName")); //$NON-NLS-1$ //$NON-NLS-2$ public static <T> PyCallable<T> wrapPyFunction(
} final String pyImportName, final Class<T> returnType) {
if (returnType == null) { if (pyImportName == null) {
throw new IllegalArgumentException(_("JyWrapper.6", "returnType")); //$NON-NLS-1$ //$NON-NLS-2$ throw new IllegalArgumentException(_("JyWrapper.6", "pyImportName")); //$NON-NLS-1$ //$NON-NLS-2$
} }
if (returnType == null) {
final PyObject pyImport = PyImportLoader.loadPyImport(pyImportName); throw new IllegalArgumentException(_("JyWrapper.6", "returnType")); //$NON-NLS-1$ //$NON-NLS-2$
if (!(pyImport instanceof PyFunction)) { }
throw new IllegalArgumentException(_("JyWrapper.0", pyImportName)); //$NON-NLS-1$
} final PyObject pyImport = PyImportLoader.loadPyImport(pyImportName);
if (!(pyImport instanceof PyFunction)) {
@SuppressWarnings("unchecked") throw new IllegalArgumentException(_("JyWrapper.0", pyImportName)); //$NON-NLS-1$
final PyCallable<T> newInstance = PyObjectProxy.newInstance( }
pyImport, PyCallable.class);
return newInstance; @SuppressWarnings("unchecked")
} final PyCallable<T> newInstance = PyObjectProxy.newInstance(
pyImport, PyCallable.class);
} return newInstance;
}
}

View File

@ -1,28 +1,28 @@
package net.abhinavsarkar.jywrapper; package net.abhinavsarkar.jywrapper;
import java.text.MessageFormat; import java.text.MessageFormat;
import java.util.MissingResourceException; import java.util.MissingResourceException;
import java.util.ResourceBundle; import java.util.ResourceBundle;
final class Messages { final class Messages {
private static final String BUNDLE_NAME = "net.abhinavsarkar.jywrapper.messages"; //$NON-NLS-1$ private static final String BUNDLE_NAME = "net.abhinavsarkar.jywrapper.messages"; //$NON-NLS-1$
private static final ResourceBundle RESOURCE_BUNDLE = ResourceBundle private static final ResourceBundle RESOURCE_BUNDLE =
.getBundle(BUNDLE_NAME); ResourceBundle.getBundle(BUNDLE_NAME);
private Messages() { private Messages() {
} }
public static String getString(String key) { public static String getString(final String key) {
try { try {
return RESOURCE_BUNDLE.getString(key); return RESOURCE_BUNDLE.getString(key);
} catch (MissingResourceException e) { } catch (final MissingResourceException e) {
return '!' + key + '!'; return '!' + key + '!';
} }
} }
public static String _(final String messageKey, final Object... arguments) { public static String _(final String messageKey, final Object... arguments) {
return new MessageFormat(getString(messageKey)) return new MessageFormat(getString(messageKey))
.format(arguments, new StringBuffer(), null).toString(); .format(arguments, new StringBuffer(), null).toString();
} }
} }

View File

@ -1,17 +1,18 @@
package net.abhinavsarkar.jywrapper; package net.abhinavsarkar.jywrapper;
import net.abhinavsarkar.jywrapper.PyObjectProxy.MemberType; import net.abhinavsarkar.jywrapper.PyObjectProxy.MemberType;
public enum PyAttributeType { public enum PyAttributeType {
GETTER(MemberType.GETTER), SETTER(MemberType.SETTER), CONST(MemberType.CONST);
GETTER(MemberType.GETTER), SETTER(MemberType.SETTER), CONST(MemberType.CONST);
private final MemberType memberType;
private final MemberType memberType;
private PyAttributeType(MemberType memberType) {
this.memberType = memberType; private PyAttributeType(final MemberType memberType) {
} this.memberType = memberType;
}
public MemberType getMemberType() {
return memberType; MemberType getMemberType() {
} return memberType;
} }
}

View File

@ -1,62 +1,62 @@
package net.abhinavsarkar.jywrapper; package net.abhinavsarkar.jywrapper;
import static net.abhinavsarkar.jywrapper.Messages._; import static net.abhinavsarkar.jywrapper.Messages._;
import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentHashMap;
import net.abhinavsarkar.jywrapper.exception.PythonImportNotFoundException; import net.abhinavsarkar.jywrapper.exception.PythonImportNotFoundException;
import org.python.core.Py; import org.python.core.Py;
import org.python.core.PyException; import org.python.core.PyException;
import org.python.core.PyObject; import org.python.core.PyObject;
import org.python.core.PySystemState; import org.python.core.PySystemState;
/** /**
* @author AbhinavSarkar * @author AbhinavSarkar
* *
*/ */
public final class PyImportLoader { public final class PyImportLoader {
private static final PyObject importer = new PySystemState().getBuiltins() private static final PyObject importer = new PySystemState().getBuiltins()
.__getitem__(Py.newString("__import__")); //$NON-NLS-1$ .__getitem__(Py.newString("__import__")); //$NON-NLS-1$
private static final ConcurrentHashMap<String, PyObject> loadedPyImports = private static final ConcurrentHashMap<String, PyObject> loadedPyImports =
new ConcurrentHashMap<String, PyObject>(); new ConcurrentHashMap<String, PyObject>();
private PyImportLoader() { private PyImportLoader() {
} }
/** /**
* @param fullImportName * @param fullImportName
* @return * @return
* @throws PythonImportNotFoundException * @throws PythonImportNotFoundException
*/ */
public static PyObject loadPyImport(String fullImportName) public static PyObject loadPyImport(final String fullImportName)
throws PythonImportNotFoundException { throws PythonImportNotFoundException {
if (!loadedPyImports.containsKey(fullImportName)) { if (!loadedPyImports.containsKey(fullImportName)) {
int i = fullImportName.lastIndexOf('.'); final int i = fullImportName.lastIndexOf('.');
String errorMsg = _("PyImportLoader.1", fullImportName); //$NON-NLS-1$ final String errorMsg = _("PyImportLoader.1", fullImportName); //$NON-NLS-1$
PyObject pyImport; PyObject pyImport;
if (i == -1) { if (i == -1) {
String pyModuleName = fullImportName; final String pyModuleName = fullImportName;
try { try {
pyImport = importer.__call__(Py.newString(pyModuleName)); pyImport = importer.__call__(Py.newString(pyModuleName));
} catch (PyException pye) { } catch (final PyException pye) {
throw new PythonImportNotFoundException(errorMsg, pye); throw new PythonImportNotFoundException(errorMsg, pye);
} }
} else { } else {
String pyModuleName = fullImportName.substring(0, i); final String pyModuleName = fullImportName.substring(0, i);
String pyClassName = fullImportName.substring(i + 1); final String pyClassName = fullImportName.substring(i + 1);
try { try {
pyImport = importer.__call__(Py.newString(pyModuleName)) pyImport = importer.__call__(Py.newString(pyModuleName))
.__getattr__(pyClassName); .__getattr__(pyClassName);
} catch (PyException pye) { } catch (final PyException pye) {
throw new PythonImportNotFoundException(errorMsg, pye); throw new PythonImportNotFoundException(errorMsg, pye);
} }
} }
loadedPyImports.putIfAbsent(fullImportName, pyImport); loadedPyImports.putIfAbsent(fullImportName, pyImport);
} }
return loadedPyImports.get(fullImportName); return loadedPyImports.get(fullImportName);
} }
} }

View File

@ -1,20 +1,20 @@
package net.abhinavsarkar.jywrapper; package net.abhinavsarkar.jywrapper;
import net.abhinavsarkar.jywrapper.PyObjectProxy.MemberType; import net.abhinavsarkar.jywrapper.PyObjectProxy.MemberType;
public enum PyMethodType { public enum PyMethodType {
INIT(MemberType.INIT), INIT (MemberType.INIT),
DIRECT(MemberType.DIRECT), DIRECT (MemberType.DIRECT),
UNDERSCORED(MemberType.UNDERSCORED), UNDERSCORED (MemberType.UNDERSCORED),
NUMERIC(MemberType.NUMERIC); NUMERIC (MemberType.NUMERIC);
private final MemberType memberType; private final MemberType memberType;
private PyMethodType(MemberType memberType) { private PyMethodType(final MemberType memberType) {
this.memberType = memberType; this.memberType = memberType;
} }
public MemberType getMemberType() { MemberType getMemberType() {
return memberType; return memberType;
} }
} }

File diff suppressed because it is too large Load Diff

View File

@ -1,75 +1,86 @@
package net.abhinavsarkar.jywrapper; package net.abhinavsarkar.jywrapper;
import static net.abhinavsarkar.jywrapper.Messages._; import static net.abhinavsarkar.jywrapper.Messages._;
import org.python.core.Py; import org.python.core.Py;
import org.python.core.PyFunction; import org.python.core.PyClass;
import org.python.core.PyModule; import org.python.core.PyFunction;
import org.python.core.PyObject; import org.python.core.PyModule;
import org.python.core.PyString; import org.python.core.PyObject;
import org.python.core.PyType; import org.python.core.PyString;
import org.python.core.PyType;
final class Util {
final class Util {
private Util() {
} private Util() {
}
static <T> T py2Java(final PyObject pyObject, final Class<T> javaClass) {
final Object javaWrapper = pyObject.__tojava__(javaClass); static <T> T py2Java(final PyObject pyObject, final Class<T> javaClass) {
if (javaWrapper == Py.NoConversion) { final Object javaWrapper = pyObject.__tojava__(javaClass);
if (javaClass.isInterface()) { if (javaWrapper == Py.NoConversion) {
return PyObjectProxy.newInstance(pyObject, javaClass); if (javaClass.isInterface()) {
} else { return PyObjectProxy.newInstance(pyObject, javaClass);
throw new IllegalArgumentException( } else {
_("JyWrapper.1", pyObject, javaClass.getName())); //$NON-NLS-1$ throw new IllegalArgumentException(
} _("JyWrapper.1", pyObject, javaClass.getName())); //$NON-NLS-1$
} else { }
@SuppressWarnings("unchecked") } else {
final T t = (T) javaWrapper; @SuppressWarnings("unchecked")
return t; final T t = (T) javaWrapper;
} return t;
} }
}
static PyObject[] convertArgs(final Object[] args) {
if (args == null || args.length == 0) { static PyObject[] convertArgs(final Object[] args) {
return new PyObject[0]; if (args == null || args.length == 0) {
} return new PyObject[0];
if (args.length == 1) { }
return new PyObject[] { Py.java2py(args[0]) }; if (args.length == 1) {
} return new PyObject[] { Py.java2py(args[0]) };
}
final PyObject[] pyArgs = new PyObject[args.length];
for (int i = args.length; --i >= 0;) { final PyObject[] pyArgs = new PyObject[args.length];
pyArgs[i] = Py.java2py(args[i]); for (int i = args.length; --i >= 0;) {
} pyArgs[i] = Py.java2py(args[i]);
return pyArgs; }
} return pyArgs;
}
static String getPyImportName(final PyObject pyObject) {
synchronized (pyObject) { static String getPyImportName(final PyObject pyObject) {
if (pyObject instanceof PyType) { synchronized (pyObject) {
final PyType pyType = (PyType) pyObject; if (pyObject instanceof PyType) {
final PyObject module = pyType.getModule(); final PyType pyType = (PyType) pyObject;
if (module instanceof PyString final PyObject module = pyType.getModule();
&& !module.toString().equals("__builtin__")) { //$NON-NLS-1$ if (module instanceof PyString
return String.format("%s.%s", module.toString(), //$NON-NLS-1$ && !module.toString().equals("__builtin__")) { //$NON-NLS-1$
pyType.getName()); return String.format("%s.%s", module.toString(), //$NON-NLS-1$
} pyType.getName());
return pyType.getName(); }
} else if (pyObject instanceof PyModule) { return pyType.getName();
return ((PyModule) pyObject).toString(); } else if (pyObject instanceof PyClass) {
} else if (pyObject instanceof PyFunction) { final PyClass pyClass = (PyClass) pyObject;
final PyFunction pyFunction = (PyFunction) pyObject; final PyObject mod = pyClass.__dict__.__finditem__("__module__");
return String.format("%s.%s", pyFunction.__module__, //$NON-NLS-1$ String smod;
pyFunction.__name__); if (mod == null || !(mod instanceof PyString)) {
} else { smod = "<unknown>";
return getPyImportName(pyObject.getType()); } else {
} smod = ((PyString) mod).toString();
} }
} return smod + "." + pyClass.__name__;
} else if (pyObject instanceof PyModule) {
static String camelCase2UnderScore(final String word) { return ((PyModule) pyObject).toString();
return word.replaceAll("([A-Z])", "_$1").toLowerCase(); //$NON-NLS-1$ //$NON-NLS-2$ } else if (pyObject instanceof PyFunction) {
} final PyFunction pyFunction = (PyFunction) pyObject;
return String.format(
} "%s.%s", pyFunction.__module__, pyFunction.__name__); //$NON-NLS-1$
} else {
return getPyImportName(pyObject.getType());
}
}
}
static String camelCase2UnderScore(final String word) {
return word.replaceAll("([A-Z])", "_$1").toLowerCase(); //$NON-NLS-1$ //$NON-NLS-2$
}
}

View File

@ -1,17 +1,17 @@
JyWrapper.0="{0}" is not a Python Function JyWrapper.0="{0}" is not a Python Function
JyWrapper.1=Cannot convert Python object: {0} to a Java object of class {1} JyWrapper.1=Cannot convert Python object: {0} to a Java object of class {1}
JyWrapper.2=Cannot convert Python Type {0} to Java Class {1} JyWrapper.2=Cannot convert Python Type {0} to Java Class {1}
JyWrapper.3=Cannot not instantiate the Python type: {0} JyWrapper.3=Cannot not instantiate the Python type: {0}
JyWrapper.4=Python module {0} can be instantiated statically only JyWrapper.4=Python module {0} can be instantiated statically only
JyWrapper.5={0} is not a Python Type or Module JyWrapper.5={0} is not a Python Type, Class or Module
JyWrapper.6=parameter "{0}" is null JyWrapper.6=parameter "{0}" is null
JyWrapper.7=No Python import name annotated on the Java Class {0} JyWrapper.7=No Python import name annotated on the Java Class {0}
JyWrapper.8={0} is not an Interface JyWrapper.8={0} is not an Interface
JyWrapper.9=Cannot instantiate a Python non type JyWrapper.9=Cannot instantiate a non Python Type or Class
JyWrapper.10=Instance method "{0}" called on a Python Type JyWrapper.10=Instance method "{0}" called on a Python Type
JyWrapper.11=No comparison methods found in the backing Python object JyWrapper.11=No comparison methods found in the backing Python object
JyWrapper.12=Trying to get instance attribute "{0}" from a Python Type JyWrapper.12=Trying to get instance attribute "{0}" from a Python Type
JyWrapper.13=Can''t set attribute: {0} JyWrapper.13=Can''t set attribute: {0}
JyWrapper.14=Trying to set instance attribute "{0}" in a python class JyWrapper.14=Trying to set instance attribute "{0}" in a python class
JyWrapper.15=No {0} named "{1}" in the backing Python Type {2} JyWrapper.15=No {0} named "{1}" in the backing Python Type {2}
PyImportLoader.1=Python Import "{0}" not found in pythonpath PyImportLoader.1=Python Import "{0}" not found in pythonpath