-
-
Notifications
You must be signed in to change notification settings - Fork 4.1k
/
BuiltinModule.scala
142 lines (129 loc) · 6.01 KB
/
BuiltinModule.scala
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
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
/*
* Copyright (C) Lightbend Inc. <https://www.lightbend.com>
*/
package play.api.inject
import java.util.concurrent.Executor
import javax.inject.Inject
import javax.inject.Provider
import javax.inject.Singleton
import akka.actor.ActorSystem
import akka.actor.CoordinatedShutdown
import akka.actor.typed.Scheduler
import akka.stream.Materializer
import com.typesafe.config.Config
import play.api._
import play.api.http.HttpConfiguration._
import play.api.http._
import play.api.libs.Files.TemporaryFileReaperConfigurationProvider
import play.api.libs.Files._
import play.api.libs.concurrent._
import play.api.mvc._
import play.api.mvc.request.DefaultRequestFactory
import play.api.mvc.request.RequestFactory
import play.api.routing.Router
import play.core.j.JavaRouterAdapter
import play.core.routing.GeneratedRouter
import play.libs.concurrent.HttpExecutionContext
import scala.concurrent.ExecutionContext
import scala.concurrent.ExecutionContextExecutor
/**
* The Play BuiltinModule.
*
* Provides all the core components of a Play application. This is typically automatically enabled by Play for an
* application.
*/
class BuiltinModule
extends SimpleModule((env, conf) => {
def dynamicBindings(factories: ((Environment, Configuration) => Seq[Binding[_]])*) = {
factories.flatMap(_(env, conf))
}
Seq(
bind[Environment] to env,
bind[ConfigurationProvider].to(new ConfigurationProvider(conf)),
bind[Configuration].toProvider[ConfigurationProvider],
bind[Config].toProvider[ConfigProvider],
bind[HttpConfiguration].toProvider[HttpConfigurationProvider],
bind[ParserConfiguration].toProvider[ParserConfigurationProvider],
bind[CookiesConfiguration].toProvider[CookiesConfigurationProvider],
bind[FlashConfiguration].toProvider[FlashConfigurationProvider],
bind[SessionConfiguration].toProvider[SessionConfigurationProvider],
bind[ActionCompositionConfiguration].toProvider[ActionCompositionConfigurationProvider],
bind[FileMimeTypesConfiguration].toProvider[FileMimeTypesConfigurationProvider],
bind[SecretConfiguration].toProvider[SecretConfigurationProvider],
bind[TemporaryFileReaperConfiguration].toProvider[TemporaryFileReaperConfigurationProvider],
bind[CookieHeaderEncoding].to[DefaultCookieHeaderEncoding],
bind[RequestFactory].to[DefaultRequestFactory],
bind[TemporaryFileReaper].to[DefaultTemporaryFileReaper],
bind[TemporaryFileCreator].to[DefaultTemporaryFileCreator],
bind[PlayBodyParsers].to[DefaultPlayBodyParsers],
bind[BodyParsers.Default].toSelf,
bind[DefaultActionBuilder].to[DefaultActionBuilderImpl],
bind[ControllerComponents].to[DefaultControllerComponents],
bind[MessagesActionBuilder].to[DefaultMessagesActionBuilderImpl],
bind[MessagesControllerComponents].to[DefaultMessagesControllerComponents],
bind[Futures].to[DefaultFutures],
// Application lifecycle, bound both to the interface, and its implementation, so that Application can access it
// to shut it down.
bind[DefaultApplicationLifecycle].toSelf,
bind[ApplicationLifecycle].to(bind[DefaultApplicationLifecycle]),
bind[Application].to[DefaultApplication],
bind[play.Application].to[play.DefaultApplication],
bind[play.routing.Router].to[JavaRouterAdapter],
bind[ActorSystem].toProvider[ActorSystemProvider],
bind[Materializer].toProvider[MaterializerProvider],
bind[CoordinatedShutdown].toProvider[CoordinatedShutdownProvider],
// Typed Akka Scheduler bind
bind[Scheduler].toProvider[AkkaSchedulerProvider],
bind[ExecutionContextExecutor].toProvider[ExecutionContextProvider],
bind[ExecutionContext].to(bind[ExecutionContextExecutor]),
bind[Executor].to(bind[ExecutionContextExecutor]),
bind[HttpExecutionContext].toSelf,
bind[play.core.j.JavaContextComponents].to[play.core.j.DefaultJavaContextComponents],
bind[play.core.j.JavaHandlerComponents].to[play.core.j.DefaultJavaHandlerComponents],
bind[FileMimeTypes].toProvider[DefaultFileMimeTypesProvider]
) ++ dynamicBindings(
HttpErrorHandler.bindingsFromConfiguration,
HttpFilters.bindingsFromConfiguration,
HttpRequestHandler.bindingsFromConfiguration,
ActionCreator.bindingsFromConfiguration,
RoutesProvider.bindingsFromConfiguration
)
})
// This allows us to access the original configuration via this
// provider while overriding the binding for Configuration itself.
class ConfigurationProvider(val get: Configuration) extends Provider[Configuration]
class ConfigProvider @Inject() (configuration: Configuration) extends Provider[Config] {
override def get() = configuration.underlying
}
@Singleton
class RoutesProvider @Inject() (
injector: Injector,
environment: Environment,
configuration: Configuration,
httpConfig: HttpConfiguration
) extends Provider[Router] {
lazy val get = {
val prefix = httpConfig.context
val router = Router
.load(environment, configuration)
.fold[Router](Router.empty)(injector.instanceOf(_))
router.withPrefix(prefix)
}
}
object RoutesProvider {
def bindingsFromConfiguration(environment: Environment, configuration: Configuration): Seq[Binding[_]] = {
val routerClass = Router.load(environment, configuration)
import scala.language.existentials
// inferred existential type
// Seq[play.api.inject.Binding[_$1]] forSome { type _$1 <: play.api.routing.Router },
// which cannot be expressed by wildcards
// If it's a generated router, then we need to provide a binding for it. Otherwise, it's the users
// (or the library that provided the router) job to provide a binding for it.
val routerInstanceBinding = routerClass match {
case Some(generated) if classOf[GeneratedRouter].isAssignableFrom(generated) =>
Seq(bind(generated).toSelf)
case _ => Nil
}
routerInstanceBinding :+ bind[Router].toProvider[RoutesProvider]
}
}