PageRenderTime 31ms CodeModel.GetById 15ms RepoModel.GetById 0ms 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. */
  18. package org.fusesource.scalate.util
  19. import java.io.InputStream
  20. import java.util.Properties
  21. /**
  22. * <p>
  23. * </p>
  24. *
  25. * @author <a href="http://hiramchirino.com">Hiram Chirino</a>
  26. */
  27. object ClassFinder {
  28. val log = Log(getClass); import log._
  29. def discoverCommands[T](
  30. indexPath: String,
  31. classLoaders: List[ClassLoader] = ClassLoaders.defaultClassLoaders): List[T] = {
  32. classLoaders.flatMap { cl =>
  33. ClassLoaders.withContextClassLoader(cl) {
  34. discoverCommandClasses(indexPath, cl).flatMap {
  35. name =>
  36. try {
  37. val clazz = cl.loadClass(name)
  38. try {
  39. Some(clazz.getConstructor().newInstance().asInstanceOf[T])
  40. } catch {
  41. case e: Exception =>
  42. // It may be a scala object.. check for a module class
  43. try {
  44. val moduleField = cl.loadClass(name + "$").getDeclaredField("MODULE$")
  45. Some(moduleField.get(null).asInstanceOf[T])
  46. } catch {
  47. case e2: Throwable =>
  48. // throw the original error...
  49. throw e
  50. }
  51. }
  52. } catch {
  53. case e: Throwable =>
  54. debug(e, "Invalid class: %s", name)
  55. None
  56. }
  57. }
  58. }
  59. }.distinct
  60. }
  61. def discoverCommandClasses(
  62. indexPath: String,
  63. cl: ClassLoader = getClass.getClassLoader): List[String] = {
  64. var rc: List[String] = Nil
  65. val resources = cl.getResources(indexPath)
  66. while (resources.hasMoreElements) {
  67. val url = resources.nextElement
  68. debug("loaded commands from %s", url)
  69. val p = loadProperties(url.openStream)
  70. if (p == null) {
  71. warn("Could not load class list from: %s", url)
  72. }
  73. val enum = p.keys
  74. while (enum.hasMoreElements) {
  75. rc = rc ::: enum.nextElement.asInstanceOf[String] :: Nil
  76. }
  77. }
  78. rc = rc.distinct
  79. debug("loaded classes: %s", rc)
  80. rc
  81. }
  82. def loadProperties(is: InputStream): Properties = {
  83. if (is == null) {
  84. null
  85. } else {
  86. try {
  87. val p = new Properties()
  88. p.load(is)
  89. p
  90. } catch {
  91. case e: Exception => null
  92. } finally {
  93. try {
  94. is.close()
  95. } catch {
  96. case _: Exception =>
  97. }
  98. }
  99. }
  100. }
  101. }