summaryrefslogtreecommitdiff
path: root/src/compiler/scala/tools/nsc/ObjectRunner.scala
blob: 7e3442ce0229c64f18b14d0238c4a53b84e9690d (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
/* NSC -- new Scala compiler
 * Copyright 2005-2006 LAMP/EPFL
 * @author  Lex Spoon
 */

// $Id$

package scala.tools.nsc

import java.lang.Class
import java.lang.{ClassNotFoundException, NoSuchMethodException}
import java.io.File
import java.lang.reflect.{Method,Modifier}
import java.net.URLClassLoader

/** An object that runs another object specified by name.
 *
 *  @author  Lex Spoon
 *  @version 1.0, 15/06/2006
 */
object ObjectRunner {

  /** Look up a class with a given class path.
   *
   *  @param classpath  ...
   *  @param objectName ...
   *  @return           ...
   */
  def findClass(classpath: List[String], objectName: String)
  : Option[Class] =
  {
    val classpathURLs = classpath.map(s => new File(s).toURL).toArray
    val mainLoader = new URLClassLoader(classpathURLs, null)
    try {
      Some(Class.forName(objectName, true, mainLoader))
    } catch {
      case _:ClassNotFoundException => None
    }
  }

  /** Check whether a class with the specified name
   *  exists on the specified class path.
   *
   *  @param classpath  ...
   *  @param objectName ...
   *  @return           ...
   */
  def classExists(classpath: List[String], objectName: String) =
    !(findClass(classpath, objectName).isEmpty)

  /** Run a given object, specified by name, using a
   *  specified classpath and argument list.
   *
   *  @param classpath  ...
   *  @param objectName ...
   *  @param arguments  ...
   *
   *  @throws ClassNotFoundException    ...
   *  @throws NoSuchMethodError         ...
   *  @throws InvocationTargetException ...
   */
  def run(
      classpath: List[String],
      objectName: String,
      arguments: Seq[String]): Unit =
  {
      val clsToRun = findClass(classpath, objectName) match {
        case Some(cls) => cls
        case None => throw new ClassNotFoundException(objectName)
      }

      val method = clsToRun.getMethod("main", List(classOf[Array[String]]).toArray)
      if ((method.getModifiers & Modifier.STATIC) == 0)
        throw new NoSuchMethodException(objectName + ".main is not static")

      method.invoke(null, List(arguments.toArray).toArray)
  }
}