From 9d24efb389c5b0c5107faf7f3255ee5ccd4515cf Mon Sep 17 00:00:00 2001 From: michelou Date: Tue, 4 May 2004 14:23:16 +0000 Subject: *** empty log message *** --- sources/examples/mobile/sort.scala | 17 +++ sources/scala/mobile/Code.scala | 230 ++++++++++++++++++++++++++++++++++++ sources/scala/mobile/Location.scala | 75 ++++++++++++ 3 files changed, 322 insertions(+) create mode 100644 sources/examples/mobile/sort.scala create mode 100644 sources/scala/mobile/Code.scala create mode 100644 sources/scala/mobile/Location.scala (limited to 'sources') diff --git a/sources/examples/mobile/sort.scala b/sources/examples/mobile/sort.scala new file mode 100644 index 0000000000..62818467fa --- /dev/null +++ b/sources/examples/mobile/sort.scala @@ -0,0 +1,17 @@ +package examples.mobile; + +import java.net._; +import scala.mobile._; + + +object sort with Application { + val url = new URL("http://scala.epfl.ch/classes/examples.jar"); + + val location = new Location(url); + val obj = location create "examples.sort"; + val ar = Array(6, 2, 8, 5, 1); + obj[Array[Int], Unit]("println")(ar); + obj[Array[Int], Unit]("sort")(ar); + obj[Array[Int], Unit]("println")(ar); + Console.println +} diff --git a/sources/scala/mobile/Code.scala b/sources/scala/mobile/Code.scala new file mode 100644 index 0000000000..79d9eaca10 --- /dev/null +++ b/sources/scala/mobile/Code.scala @@ -0,0 +1,230 @@ +/* __ *\ +** ________ ___ / / ___ Scala API ** +** / __/ __// _ | / / / _ | (c) 2002-2004, LAMP/EPFL ** +** __\ \/ /__/ __ |/ /__/ __ | ** +** /____/\___/_/ |_/____/_/ | | ** +** |/ ** +** $Id$ +\* */ + +package scala.mobile; + +import java.lang.reflect.Constructor; +import java.lang.reflect.Method; +import java.lang.reflect.Modifier; + + +/** The clase Code provides apply methods + * with different arities (actually up to 9 parameters) to invoke + * a function simply by specifying its name and argument types. + * + * Example:
+ *    val url = new URL("http://scala.epfl.ch/classes/examples.jar");
+ *    val obj = new Location(url) create "examples.sort";
+ *    val ar = Array(6, 2, 8, 5, 1);
+ *    obj[Array[Int], Unit]("println")(ar);
+ *    obj[Array[Int], Unit]("sort")(ar);
+ *    obj[Array[Int], Unit]("println")(ar);
+ * + * @author Stephane Micheloud + * @version 1.0, 04/05/2004 + */ +class Code(clazz: java.lang.Class) { + + private type JObject = java.lang.Object; + + private var instance: JObject = _; + + ///////////////////////////// apply methods /////////////////////////////// + + def apply[R](funName: String) = + () => { + val args = Predef.Array[JObject](); + val types = Predef.Array[Class](); + applyFun(funName, args, types).asInstanceOf[R]; + }; + + def apply[A0, R](funName: String) = + (_0: A0) => { + val p = boxValue(_0); + val args = Predef.Array(p._1); + val types = Predef.Array(p._2); + applyFun(funName, args, types).asInstanceOf[R]; + }; + + def apply[A0, A1, R](funName: String) = + (_0: A0, _1: A1) => { + val p0 = boxValue(_0); + val p1 = boxValue(_1); + val args = Predef.Array(p0._1, p1._1); + val types = Predef.Array(p0._2, p1._2); + applyFun(funName, args, types).asInstanceOf[R]; + }; + + def apply[A0, A1, A2, R](funName: String) = + (_0: A0, _1: A1, _2: A2) => { + val p0 = boxValue(_0); + val p1 = boxValue(_1); + val p2 = boxValue(_2); + val args = Predef.Array(p0._1, p1._1, p2._1); + val types = Predef.Array(p0._2, p1._2, p2._2); + applyFun(funName, args, types).asInstanceOf[R]; + }; + + def apply[A0, A1, A2, A3, R](funName: String) = + (_0: A0, _1: A1, _2: A2, _3: A3) => { + val p0 = boxValue(_0); + val p1 = boxValue(_1); + val p2 = boxValue(_2); + val p3 = boxValue(_3); + val args = Predef.Array(p0._1, p1._1, p2._1, p3._1); + val types = Predef.Array(p0._2, p1._2, p2._2, p3._2); + applyFun(funName, args, types).asInstanceOf[R]; + }; + + def apply[A0, A1, A2, A3, A4, R](funName: String) = + (_0: A0, _1: A1, _2: A2, _3: A3, _4: A4) => { + val p0 = boxValue(_0); + val p1 = boxValue(_1); + val p2 = boxValue(_2); + val p3 = boxValue(_3); + val p4 = boxValue(_4); + val args = Predef.Array(p0._1, p1._1, p2._1, p3._1, p4._1); + val types = Predef.Array(p0._2, p1._2, p2._2, p3._2, p4._2); + applyFun(funName, args, types).asInstanceOf[R]; + }; + + def apply[A0, A1, A2, A3, A4, A5, R](funName: String) = + (_0: A0, _1: A1, _2: A2, _3: A3, _4: A4, _5: A5) => { + val p0 = boxValue(_0); + val p1 = boxValue(_1); + val p2 = boxValue(_2); + val p3 = boxValue(_3); + val p4 = boxValue(_4); + val p5 = boxValue(_5); + val args = Predef.Array(p0._1, p1._1, p2._1, p3._1, p4._1, p5._1); + val types = Predef.Array(p0._2, p1._2, p2._2, p3._2, p4._2, p5._2); + applyFun(funName, args, types).asInstanceOf[R]; + }; + + def apply[A0, A1, A2, A3, A4, A5, A6, R](funName: String) = + (_0: A0, _1: A1, _2: A2, _3: A3, _4: A4, _5: A5, _6: A6) => { + val p0 = boxValue(_0); + val p1 = boxValue(_1); + val p2 = boxValue(_2); + val p3 = boxValue(_3); + val p4 = boxValue(_4); + val p5 = boxValue(_5); + val p6 = boxValue(_6); + val args = Predef.Array(p0._1, p1._1, p2._1, p3._1, p4._1, p5._1, p6._1); + val types = Predef.Array(p0._2, p1._2, p2._2, p3._2, p4._2, p5._2, p6._2); + applyFun(funName, args, types).asInstanceOf[R]; + }; + + def apply[A0, A1, A2, A3, A4, A5, A6, A7, R](funName: String) = + (_0: A0, _1: A1, _2: A2, _3: A3, _4: A4, _5: A5, _6: A6, _7: A7) => { + val p0 = boxValue(_0); + val p1 = boxValue(_1); + val p2 = boxValue(_2); + val p3 = boxValue(_3); + val p4 = boxValue(_4); + val p5 = boxValue(_5); + val p6 = boxValue(_6); + val p7 = boxValue(_7); + val args = Predef.Array(p0._1, p1._1, p2._1, p3._1, p4._1, p5._1, p6._1, p7._1); + val types = Predef.Array(p0._2, p1._2, p2._2, p3._2, p4._2, p5._2, p6._2, p7._2); + applyFun(funName, args, types).asInstanceOf[R]; + }; + + def apply[A0, A1, A2, A3, A4, A5, A6, A7, A8, R](funName: String) = + (_0: A0, _1: A1, _2: A2, _3: A3, _4: A4, _5: A5, _6: A6, _7: A7, _8: A8) => { + val p0 = boxValue(_0); + val p1 = boxValue(_1); + val p2 = boxValue(_2); + val p3 = boxValue(_3); + val p4 = boxValue(_4); + val p5 = boxValue(_5); + val p6 = boxValue(_6); + val p7 = boxValue(_7); + val p8 = boxValue(_8); + val args = Predef.Array(p0._1, p1._1, p2._1, p3._1, p4._1, p5._1, p6._1, p7._1, p8._1); + val types = Predef.Array(p0._2, p1._2, p2._2, p3._2, p4._2, p5._2, p6._2, p7._2, p8._2); + applyFun(funName, args, types).asInstanceOf[R]; + }; + + ////////////////////// private functions /////////////////////// + + private def boxValue(value: Any) = value match { + case x: Byte => Pair(new java.lang.Byte(x), java.lang.Byte.TYPE) + case x: Boolean => Pair(new java.lang.Boolean(x), java.lang.Boolean.TYPE) + case x: Char => Pair(new java.lang.Character(x), java.lang.Character.TYPE) + case x: Short => Pair(new java.lang.Short(x), java.lang.Short.TYPE) + case x: Int => Pair(new java.lang.Integer(x), java.lang.Integer.TYPE) + case x: Long => Pair(new java.lang.Long(x), java.lang.Long.TYPE) + case x: Float => Pair(new java.lang.Float(x), java.lang.Float.TYPE) + case x: Double => Pair(new java.lang.Double(x), java.lang.Double.TYPE) + case _ => + val x = value.asInstanceOf[JObject]; + Pair(x, x.getClass()) + } + + private def isConstructorName(methName: String) = { + var className = clazz.getName(); + val classInx = className.lastIndexOf("."); + val methInx = methName.lastIndexOf("."); + if (classInx > 0 && methInx < 0) + className = className.substring(classInx + 1, className.length()); + methName.equals(className) + } + + private def applyFun(methName: String, args: Array[JObject], argTypes: Array[Class]): JObject = { + try { + val method = clazz.getMethod(methName, argTypes); + var obj: JObject = null; + if (! Modifier.isStatic(method.getModifiers())) { + if (instance == null) { + instance = try { + clazz.newInstance(); + } catch { case _ => + val cs = clazz.getConstructors(); +//Console.println("cs.length=" + cs.length); + if (cs.length > 0) { + cs(0).newInstance(Predef.Array("")) + } else { + error("class " + clazz.getName() + " has no public constructor"); + null + } + } + } + obj = instance; + } + val result = method.invoke(obj, args); + if (result == null) ().asInstanceOf[JObject] else result + } + catch { + case me: NoSuchMethodException => + if (isConstructorName(methName)) { + try { + val cstr = clazz.getConstructor(argTypes); + instance = cstr.newInstance(args); + instance + } + catch { + case e: Exception => + Console.println(e.getMessage()); + e.printStackTrace(); + } + } + else { + Console.println(me.getMessage()); + me.printStackTrace(); + } + null + case e: Exception => + Console.println(e.getMessage()); + e.printStackTrace(); + null + } + } + +} diff --git a/sources/scala/mobile/Location.scala b/sources/scala/mobile/Location.scala new file mode 100644 index 0000000000..7c8d787caf --- /dev/null +++ b/sources/scala/mobile/Location.scala @@ -0,0 +1,75 @@ +/* __ *\ +** ________ ___ / / ___ Scala API ** +** / __/ __// _ | / / / _ | (c) 2002-2004, LAMP/EPFL ** +** __\ \/ /__/ __ |/ /__/ __ | ** +** /____/\___/_/ |_/____/_/ | | ** +** |/ ** +** $Id$ +\* */ + +package scala.mobile; + +import java.net._; + +import scala.collection.mutable._; + + +/** The class Location provides a create + * method to instanciate objects from a network location by + * specifying its URL address. + * + * Example:
+ *    val url = new URL("http://scala.epfl.ch/classes/examples.jar");
+ *    val obj = new Location(url) create "examples.sort";
+ * + * @author Stephane Micheloud + * @version 1.0, 04/05/2004 + */ +class Location(url: URL) { + + /** A cache containing all class loaders of this location. + */ + private var lcache: Map[URL, ClassLoader] = new HashMap; + + /** The class loader associated with this location. + */ + private val loader = if (url == null) + ClassLoader.getSystemClassLoader() + else + lcache.get(url) match { + case Some(cl) => + cl + case _ => + val cl = new URLClassLoader(Predef.Array(url)); + lcache(url) = cl; + cl + }; + + /** A cache containing all classes of this location. + */ + private var ccache: Map[String, java.lang.Class] = new HashMap; + + def create(className: String): Code = { + val clazz = ccache.get(className) match { + case Some(x) => + x + case _ => + val clazz = if (loader.loadClass(className).isInterface()) { + // Scala source: class A { ... }; + // Java bytecode: interface A.class + class A$class.class + loader.loadClass(className + "$class"); + } + else { + // Scala source: object A { ... }; + // Java bytecode: interface A.class + class A$.class + loader.loadClass(className + "$"); + } + ccache(className) = clazz; + clazz + }; + new Code(clazz) + } + +} + +object Location extends Location(null); -- cgit v1.2.3