diff options
author | Jakob Odersky <jakob@driver.xyz> | 2018-08-22 12:51:36 -0700 |
---|---|---|
committer | Jakob Odersky <jakob@driver.xyz> | 2018-09-12 14:17:39 -0700 |
commit | 5ec270aa98b806f32338fa25357abdf45dd0625b (patch) | |
tree | f1423f8add00cc2f899d2f8259b9ab33ba3c914b /src/main/scala/xyz/driver/core/init/BuildInfoReflection.scala | |
parent | 3eb6a9e96bd8bf111490f390ea94a1c6d7677eff (diff) | |
download | driver-core-5ec270aa98b806f32338fa25357abdf45dd0625b.tar.gz driver-core-5ec270aa98b806f32338fa25357abdf45dd0625b.tar.bz2 driver-core-5ec270aa98b806f32338fa25357abdf45dd0625b.zip |
Trait-based initialization and other utilities
Adds the concept of a 'platform', a centralized place in which
environment-specific information will be managed, and provides common
initialization logic for most "standard" apps.
As part of the common initialization, other parts of core have also
been reworked:
- HTTP-related unmarshallers and path matchers have been factored out
from core.json to a new core.rest.directives package (core.json
extends those unmarshallers and matchers for backwards
compatibility)
- CORS handling has also been moved to a dedicated utility trait
- Some custom headers have been moved from raw headers to typed ones
in core.rest.headers
- The concept of a "reporter" has been introduced. A reporter is a
context-aware combination of tracing and logging. It is intended to
issue diagnostic messages that can be traced across service
boundaries.
Closes #192
Closes #195
Diffstat (limited to 'src/main/scala/xyz/driver/core/init/BuildInfoReflection.scala')
-rw-r--r-- | src/main/scala/xyz/driver/core/init/BuildInfoReflection.scala | 37 |
1 files changed, 37 insertions, 0 deletions
diff --git a/src/main/scala/xyz/driver/core/init/BuildInfoReflection.scala b/src/main/scala/xyz/driver/core/init/BuildInfoReflection.scala new file mode 100644 index 0000000..0e53085 --- /dev/null +++ b/src/main/scala/xyz/driver/core/init/BuildInfoReflection.scala @@ -0,0 +1,37 @@ +package xyz.driver.core +package init + +import scala.reflect.runtime +import scala.util.Try +import scala.util.control.NonFatal + +/** Utility object to retrieve fields from static build configuration objects. */ +private[init] object BuildInfoReflection { + + final val BuildInfoName = "xyz.driver.BuildInfo" + + lazy val name: String = get[String]("name") + lazy val version: Option[String] = find[String]("version") + + /** Lookup a given field in the build configuration. This field is required to exist. */ + private def get[A](fieldName: String): A = + try { + val mirror = runtime.currentMirror + val module = mirror.staticModule(BuildInfoName) + val instance = mirror.reflectModule(module).instance + val accessor = module.info.decl(mirror.universe.TermName(fieldName)).asMethod + mirror.reflect(instance).reflectMethod(accessor).apply().asInstanceOf[A] + } catch { + case NonFatal(err) => + throw new RuntimeException( + s"Cannot find field name '$fieldName' in $BuildInfoName. Please define (or generate) a singleton " + + s"object with that field. Alternatively, in order to avoid runtime reflection, you may override the " + + s"caller with a static value.", + err + ) + } + + /** Try finding a given field in the build configuration. If the field does not exist, None is returned. */ + private def find[A](fieldName: String): Option[A] = Try { get[A](fieldName) }.toOption + +} |