From: <cg...@us...> - 2009-08-23 19:05:39
|
Revision: 6712 http://jython.svn.sourceforge.net/jython/?rev=6712&view=rev Author: cgroves Date: 2009-08-23 19:05:32 +0000 (Sun, 23 Aug 2009) Log Message: ----------- Kill __javaname__ as a method of setting the classname on generated proxy classes. Instead, add a couple simple proxy makers to a new module, javaproxymaker, that allow proxy classes to be created with a custom proxy name or with the fully qualfied python module + class name. Also, simplify the callable for __proxymaker__ to take Java superclass, Java interfaces, fully qualified Python class name and python class dict. Modified Paths: -------------- branches/customizable-proxymaker/Lib/test/static_proxy.py branches/customizable-proxymaker/Lib/test/test_java_subclasses.py branches/customizable-proxymaker/src/org/python/compiler/JavaMaker.java branches/customizable-proxymaker/src/org/python/core/MakeProxies.java Added Paths: ----------- branches/customizable-proxymaker/Lib/javaproxymaker.py branches/customizable-proxymaker/Lib/test/test_javaproxymaker.py Added: branches/customizable-proxymaker/Lib/javaproxymaker.py =================================================================== --- branches/customizable-proxymaker/Lib/javaproxymaker.py (rev 0) +++ branches/customizable-proxymaker/Lib/javaproxymaker.py 2009-08-23 19:05:32 UTC (rev 6712) @@ -0,0 +1,8 @@ +from org.python.compiler import JavaMaker as NamedProxyMaker + +def make_proxynamer(classname): + def make_proxymaker(superclass, interfaces, pythonClassName, pythonClassDict): + proxymaker = NamedProxyMaker(superclass, interfaces, pythonClassName, pythonClassDict) + proxymaker.proxyClassName = classname + return proxymaker + return make_proxymaker Modified: branches/customizable-proxymaker/Lib/test/static_proxy.py =================================================================== --- branches/customizable-proxymaker/Lib/test/static_proxy.py 2009-08-23 18:45:25 UTC (rev 6711) +++ branches/customizable-proxymaker/Lib/test/static_proxy.py 2009-08-23 19:05:32 UTC (rev 6712) @@ -1,9 +1,10 @@ # Part of test_java_subclasses.StaticProxyCompilationTest. This needs to be its own module # so the statically compiled proxy can import it. from java.lang import Runnable +from javaproxymaker import NamedProxyMaker class RunnableImpl(Runnable): - __javaname__ = "test.static_proxy.RunnableImpl" + __proxymaker__ = NamedProxyMaker def run(self): pass Modified: branches/customizable-proxymaker/Lib/test/test_java_subclasses.py =================================================================== --- branches/customizable-proxymaker/Lib/test/test_java_subclasses.py 2009-08-23 18:45:25 UTC (rev 6711) +++ branches/customizable-proxymaker/Lib/test/test_java_subclasses.py 2009-08-23 19:05:32 UTC (rev 6712) @@ -323,56 +323,10 @@ self.assertEquals(len(called), 1) -class SettingJavaClassNameTest(unittest.TestCase): - def test_setting_name(self): - class Fixedname(Runnable): - __javaname__ = 'name.set.in.Python' - def run(self): - pass - self.assertEquals('name.set.in.Python', Fixedname().getClass().name) - try: - class NumberPackageName(Runnable): - __javaname__ = 'ok.7.ok' - def run(self): - pass - self.fail("Shouldn't be able to set a package name that starts with a digit") - except TypeError: - pass - try: - class LiteralPackageName(Runnable): - __javaname__ = 'ok.true.ok' - def run(self): - pass - self.fail("Shouldn't be able to use a Java literal as a package name") - except TypeError: - pass - -class StaticProxyCompilationTest(unittest.TestCase): - def setUp(self): - self.orig_proxy_dir = sys.javaproxy_dir - sys.javaproxy_dir = tempfile.mkdtemp() - - def tearDown(self): - sys.javaproxy_dir = self.orig_proxy_dir - - def test_proxies_without_classloader(self): - # importing with proxy_dir set compiles RunnableImpl there - import static_proxy - - # Use the existing environment with the proxy dir added on the classpath - env = dict(os.environ) - env["CLASSPATH"] = sys.javaproxy_dir - script = test_support.findfile("import_as_java_class.py") - self.assertEquals(subprocess.call([sys.executable, "-J-Dpython.cachedir.skip=true", - script], env=env), - 0) - def test_main(): test_support.run_unittest(InterfaceTest, TableModelTest, AutoSuperTest, PythonSubclassesTest, AbstractOnSyspathTest, - ContextClassloaderTest, - SettingJavaClassNameTest, - StaticProxyCompilationTest) + ContextClassloaderTest) Added: branches/customizable-proxymaker/Lib/test/test_javaproxymaker.py =================================================================== --- branches/customizable-proxymaker/Lib/test/test_javaproxymaker.py (rev 0) +++ branches/customizable-proxymaker/Lib/test/test_javaproxymaker.py 2009-08-23 19:05:32 UTC (rev 6712) @@ -0,0 +1,59 @@ +import os +import subprocess +import sys +import tempfile +import unittest + +from test import test_support + +from java.lang import Runnable + +from javaproxymaker import make_proxynamer, NamedProxyMaker + +class SettingJavaClassNameTest(unittest.TestCase): + def test_setting_name(self): + class Fixedname(Runnable): + __proxymaker__ = make_proxynamer('name.set.in.Python') + def run(self): + pass + self.assertEquals('name.set.in.Python', Fixedname().getClass().name) + try: + class NumberPackageName(Runnable): + __proxymaker__ = make_proxynamer('ok.7.ok') + def run(self): + pass + self.fail("Shouldn't be able to set a package name that starts with a digit") + except TypeError: + pass + try: + class LiteralPackageName(Runnable): + __proxymaker__ = make_proxynamer('ok.true.ok') + def run(self): + pass + self.fail("Shouldn't be able to use a Java literal as a package name") + except TypeError: + pass + +class StaticProxyCompilationTest(unittest.TestCase): + def setUp(self): + self.orig_proxy_dir = sys.javaproxy_dir + sys.javaproxy_dir = tempfile.mkdtemp() + + def tearDown(self): + sys.javaproxy_dir = self.orig_proxy_dir + + def test_proxies_without_classloader(self): + # importing with proxy_dir set compiles RunnableImpl there + import static_proxy + + # Use the existing environment with the proxy dir added on the classpath + env = dict(os.environ) + env["CLASSPATH"] = sys.javaproxy_dir + script = test_support.findfile("import_as_java_class.py") + self.assertEquals(subprocess.call([sys.executable, "-J-Dpython.cachedir.skip=true", + script], env=env), + 0) + +def test_main(): + test_support.run_unittest(SettingJavaClassNameTest, + StaticProxyCompilationTest) Modified: branches/customizable-proxymaker/src/org/python/compiler/JavaMaker.java =================================================================== --- branches/customizable-proxymaker/src/org/python/compiler/JavaMaker.java 2009-08-23 18:45:25 UTC (rev 6711) +++ branches/customizable-proxymaker/src/org/python/compiler/JavaMaker.java 2009-08-23 19:05:32 UTC (rev 6712) @@ -8,22 +8,26 @@ public class JavaMaker extends ProxyMaker { - public String pythonClass, pythonModule; + public final String pythonClass, pythonModule; - protected PyObject dict; + public PyObject dict; private final boolean proxyNeeded; public JavaMaker(Class<?> superclass, Class<?>[] interfaces, - String pythonClass, - String pythonModule, - String proxyClassName, + String qualifiedPythonClassName, PyObject pythonClassDict) { - super(proxyClassName, superclass, interfaces); + super(qualifiedPythonClassName, superclass, interfaces); proxyNeeded = superclass != null || interfaces.length > 0; - this.pythonClass = pythonClass; - this.pythonModule = pythonModule; + int lastDot = qualifiedPythonClassName.lastIndexOf('.'); + if (lastDot != -1) { + pythonClass = qualifiedPythonClassName.substring(lastDot + 1); + pythonModule = qualifiedPythonClassName.substring(0, lastDot); + } else { + pythonClass = qualifiedPythonClassName; + pythonModule = ""; + } this.dict = pythonClassDict; } @@ -39,7 +43,6 @@ /** * Calls __initProxy__ on this class with the given given types of parameters, which must be * available as arguments to the currently called method in the order of the parameters. - * */ protected void callInitProxy(Class<?>[] parameters, Code code) { code.visitVarInsn(ALOAD, 0); @@ -50,9 +53,7 @@ @Override public void addProxy() { - if (dict != null) { - super.addProxy(); - } + super.addProxy(); // _initProxy method Code code = classfile.addMethod("__initProxy__", makeSig("V", $objArr), Modifier.PUBLIC); Modified: branches/customizable-proxymaker/src/org/python/core/MakeProxies.java =================================================================== --- branches/customizable-proxymaker/src/org/python/core/MakeProxies.java 2009-08-23 18:45:25 UTC (rev 6711) +++ branches/customizable-proxymaker/src/org/python/core/MakeProxies.java 2009-08-23 19:05:32 UTC (rev 6712) @@ -24,17 +24,17 @@ List<Class<?>> interfaces, String className, PyObject dict) { - JavaMaker javaMaker = null; - String fullProxyName = null; - String moduleName; + String qualifiedClassName; PyObject module = dict.__finditem__("__module__"); + if (module == null) { - moduleName = "unknown_module"; + qualifiedClassName = className; } else { - moduleName = Py.tojava(module, String.class); + qualifiedClassName = module + "." + className; } Class<?>[] interfacesArr = interfaces.toArray(new Class<?>[interfaces.size()]); + JavaMaker javaMaker; // Grab the proxy maker from the class if it exists, and if it does, use the proxy class // name from the maker PyObject customProxyMaker = dict.__finditem__("__proxymaker__"); @@ -42,52 +42,35 @@ if (module == null) { throw Py.TypeError("Classes using __proxymaker__ must define __module__"); } - PyObject[] args = Py.javas2pys(superclass, interfacesArr, className, moduleName, dict); + PyObject[] args = Py.javas2pys(superclass, interfacesArr, qualifiedClassName, dict); javaMaker = Py.tojava(customProxyMaker.__call__(args), JavaMaker.class); - fullProxyName = javaMaker.proxyClassName; - } - - // Grab the proxy name from the class if it exists, and if it does, override the proxy name - // from the maker if there is one - PyObject customProxyName = dict.__finditem__("__javaname__"); - if (customProxyName != null) { - fullProxyName = Py.tojava(customProxyName, String.class); - if (javaMaker != null) { - javaMaker.proxyClassName = fullProxyName; + if (!StringUtil.isJavaClassName(javaMaker.proxyClassName)) { + throw Py.TypeError(javaMaker.proxyClassName + " isn't a valid Java class name. " + + "Classes must be valid Java identifiers: " + + "http://java.sun.com/docs/books/jls/second_edition/html/lexical.doc.html#40625"); } - } - if (fullProxyName != null) { // If we've gotten a proxy name, check if it's available on the classpath - if (!StringUtil.isJavaClassName(fullProxyName)) { - throw Py.TypeError(fullProxyName + " isn't a valid Java class name. Classes " + - "must be valid Java identifiers: " + - "http://java.sun.com/docs/books/jls/second_edition/html/lexical.doc.html#40625"); - } - Class<?> proxy = Py.findClass(fullProxyName); + Class<?> proxy = Py.findClass(javaMaker.proxyClassName); // TODO - check proxy class version if (proxy != null) { return proxy; } + } else { + javaMaker = new JavaMaker(superclass, interfacesArr, qualifiedClassName, dict); + // This is a purely dynamic proxy + javaMaker.proxyClassName = proxyPrefix + qualifiedClassName + "$" + proxyNumber++; } - if (javaMaker == null) { - if (fullProxyName == null) { - // This is a purely dynamic proxy - fullProxyName = proxyPrefix + moduleName + "$" + className + "$" + proxyNumber++; - } - javaMaker = new JavaMaker(superclass, interfacesArr, className, moduleName, - fullProxyName, dict); - } if (!javaMaker.isProxyNeeded()) { return null; } byte[] bytecode = javaMaker.make(); - if (customProxyName != null || customProxyMaker != null) { - saveBytecode(fullProxyName, bytecode, Py.getSystemState().javaproxy_dir); + if (customProxyMaker != null) { + saveBytecode(javaMaker.proxyClassName, bytecode, Py.getSystemState().javaproxy_dir); } else { - saveDebugBytecode(fullProxyName, bytecode); + saveDebugBytecode(javaMaker.proxyClassName, bytecode); } return makeClass(superclass, interfaces, javaMaker.proxyClassName, bytecode); } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |