summaryrefslogtreecommitdiff
path: root/src/library/scala/mobile/Location.scala
blob: c6f7d576487b0c2c0dec3239fdc39968de255540 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
/*                     __                                               *\
**     ________ ___   / /  ___     Scala API                            **
**    / __/ __// _ | / /  / _ |    (c) 2002-2004, LAMP/EPFL             **
**  __\ \/ /__/ __ |/ /__/ __ |                                         **
** /____/\___/_/ |_/____/_/ | |                                         **
**                          |/                                          **
** $Id$
\*                                                                      */

package scala.mobile;

import java.net._;

import scala.collection.mutable._;


/** The class <code>Location</code> provides a <code>create</code>
 *  method to instantiate objects from a network location by
 *  specifying the URL address of the jar/class file.<p/>
 *
 *  An update of the jar/class file should not break your code as far
 *  as the used class names and method signatures are the same.<p/>
 *
 *  Example:<pre>
 *    <b>val</b> url = <b>new</b> URL("http://scala.epfl.ch/classes/examples.jar");
 *    <b>val</b> obj = <b>new</b> Location(url) create "examples.sort";</pre>
 *
 *  @see <a href="Code-class.html">Code</a>
 *
 *  @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;

  /** Return the code description for the string <code>className</code>
   *  at this location.
   *
   * @param the name of the class
   * @return the code description corresponding to <code>className</code>
   */
  def create(className: String) = new Code(
    ccache.get(className) match {
      case Some(clazz) =>
        clazz
      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
    }
  );

}

/** The object <code>Location</code> can be used to instantiate
 *  objects on the same Java VM. It is just provided to illustrate
 *  the special case where resources are available locally.<p/>
 *
 *  Example:<pre>
 *    <b>val</b> obj = Location.create("xcode.Math");
 *    <b>val</b> x = obj[Int, Int]("square")(5);</pre>
 *
 *  @author  Stephane Micheloud
 *  @version 1.0, 04/05/2004
 */
object Location extends Location(null);