PageRenderTime 127ms CodeModel.GetById 106ms app.highlight 15ms RepoModel.GetById 1ms app.codeStats 0ms

/scalate-util/src/main/scala/org/fusesource/scalate/util/ClassFinder.scala

http://github.com/scalate/scalate
Scala | 108 lines | 76 code | 7 blank | 25 comment | 7 complexity | 54f312ebd3a76414e5c8b7e02ffdd6b8 MD5 | raw file
  1/**
  2 * Copyright (C) 2009-2011 the original author or authors.
  3 * See the notice.md file distributed with this work for additional
  4 * information regarding copyright ownership.
  5 *
  6 * Licensed under the Apache License, Version 2.0 (the "License");
  7 * you may not use this file except in compliance with the License.
  8 * You may obtain a copy of the License at
  9 *
 10 *     http://www.apache.org/licenses/LICENSE-2.0
 11 *
 12 * Unless required by applicable law or agreed to in writing, software
 13 * distributed under the License is distributed on an "AS IS" BASIS,
 14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 15 * See the License for the specific language governing permissions and
 16 * limitations under the License.
 17 */
 18package org.fusesource.scalate.util
 19
 20import java.io.InputStream
 21import java.util.Properties
 22
 23/**
 24 * <p>
 25 * </p>
 26 *
 27 * @author <a href="http://hiramchirino.com">Hiram Chirino</a>
 28 */
 29object ClassFinder {
 30
 31  val log = Log(getClass); import log._
 32
 33  def discoverCommands[T](
 34    indexPath: String,
 35    classLoaders: List[ClassLoader] = ClassLoaders.defaultClassLoaders): List[T] = {
 36    classLoaders.flatMap { cl =>
 37      ClassLoaders.withContextClassLoader(cl) {
 38        discoverCommandClasses(indexPath, cl).flatMap {
 39          name =>
 40            try {
 41              val clazz = cl.loadClass(name)
 42              try {
 43                Some(clazz.getConstructor().newInstance().asInstanceOf[T])
 44              } catch {
 45                case e: Exception =>
 46                  // It may be a scala object.. check for a module class
 47                  try {
 48                    val moduleField = cl.loadClass(name + "$").getDeclaredField("MODULE$")
 49                    Some(moduleField.get(null).asInstanceOf[T])
 50                  } catch {
 51                    case e2: Throwable =>
 52                      // throw the original error...
 53                      throw e
 54                  }
 55              }
 56            } catch {
 57              case e: Throwable =>
 58                debug(e, "Invalid class: %s", name)
 59                None
 60            }
 61        }
 62      }
 63    }.distinct
 64  }
 65
 66  def discoverCommandClasses(
 67    indexPath: String,
 68    cl: ClassLoader = getClass.getClassLoader): List[String] = {
 69    var rc: List[String] = Nil
 70    val resources = cl.getResources(indexPath)
 71    while (resources.hasMoreElements) {
 72      val url = resources.nextElement
 73      debug("loaded commands from %s", url)
 74      val p = loadProperties(url.openStream)
 75      if (p == null) {
 76        warn("Could not load class list from: %s", url)
 77      }
 78      val enum = p.keys
 79      while (enum.hasMoreElements) {
 80        rc = rc ::: enum.nextElement.asInstanceOf[String] :: Nil
 81      }
 82    }
 83    rc = rc.distinct
 84    debug("loaded classes: %s", rc)
 85    rc
 86  }
 87
 88  def loadProperties(is: InputStream): Properties = {
 89    if (is == null) {
 90      null
 91    } else {
 92      try {
 93        val p = new Properties()
 94        p.load(is)
 95        p
 96      } catch {
 97        case e: Exception => null
 98      } finally {
 99        try {
100          is.close()
101        } catch {
102          case _: Exception =>
103        }
104      }
105    }
106  }
107
108}