play.ContextBasedBuiltInComponents Maven / Gradle / Ivy
The newest version!
/*
* Copyright (C) from 2022 The Play Framework Contributors , 2011-2021 Lightbend Inc.
*/
package play;
import static play.libs.F.LazySupplier.lazy;
import akka.actor.ActorSystem;
import akka.actor.CoordinatedShutdown;
import com.typesafe.config.Config;
import java.util.Optional;
import java.util.function.Supplier;
import play.api.Configuration;
import play.api.OptionalDevContext;
import play.api.OptionalSourceMapper;
import play.api.http.DefaultFileMimeTypesProvider;
import play.api.http.JavaCompatibleHttpRequestHandler;
import play.api.i18n.DefaultLangsProvider;
import play.api.inject.NewInstanceInjector$;
import play.api.inject.SimpleInjector;
import play.api.libs.concurrent.ActorSystemProvider;
import play.api.libs.concurrent.CoordinatedShutdownProvider;
import play.api.mvc.request.DefaultRequestFactory;
import play.api.mvc.request.RequestFactory;
import play.core.DefaultWebCommands;
import play.core.SourceMapper;
import play.core.WebCommands;
import play.core.j.JavaHttpErrorHandlerAdapter;
import play.core.j.MappedJavaHandlerComponents;
import play.http.DefaultHttpErrorHandler;
import play.http.DefaultHttpFilters;
import play.http.HttpErrorHandler;
import play.http.HttpRequestHandler;
import play.i18n.Langs;
import play.inject.ApplicationLifecycle;
import play.libs.Files;
import play.libs.crypto.CSRFTokenSigner;
import play.libs.crypto.CookieSigner;
import play.libs.crypto.DefaultCSRFTokenSigner;
import play.libs.crypto.DefaultCookieSigner;
import play.mvc.BodyParser;
import play.mvc.FileMimeTypes;
import scala.collection.immutable.Map$;
import scala.jdk.javaapi.OptionConverters;
/**
* This helper class provides all the built-in component dependencies by trading them for a single
* dependency - the {@linkplain #context() application loader context}.
*/
public abstract class ContextBasedBuiltInComponents implements BuiltInComponents {
// Class instances to emulate singleton behavior
private final Supplier _application = lazy(this::createApplication);
private final Supplier _langs = lazy(this::createLangs);
private final Supplier _fileMimeTypes = lazy(this::createFileMimeTypes);
private final Supplier _httpRequestHandler =
lazy(this::createHttpRequestHandler);
private final Supplier _actorSystem = lazy(this::createActorSystem);
private final Supplier _coordinatedShutdown =
lazy(this::createCoordinatedShutdown);
private final Supplier _cookieSigner = lazy(this::createCookieSigner);
private final Supplier _csrfTokenSigner = lazy(this::createCsrfTokenSigner);
private final Supplier _tempFileCreator =
lazy(this::createTempFileCreator);
private final Supplier _httpErrorHandler = lazy(this::createHttpErrorHandler);
private final Supplier _javaHandlerComponents =
lazy(this::createJavaHandlerComponents);
private final Supplier _webCommands = lazy(this::createWebCommands);
/**
* Returns the application loader context. The implementation should return a stable, effectively
* singleton value.
*/
public abstract ApplicationLoader.Context context();
@Override
public Config config() {
return context().initialConfig();
}
@Override
public Environment environment() {
return context().environment();
}
@Override
public Optional sourceMapper() {
// Using `devContext()` method here instead of `context.sourceMapper()` because it will then
// respect any overrides a user might define.
return devContext().map(play.api.ApplicationLoader.DevContext::sourceMapper);
}
@Override
public Optional devContext() {
return context().devContext();
}
@Override
public ApplicationLifecycle applicationLifecycle() {
return context().applicationLifecycle();
}
@Override
public WebCommands webCommands() {
// We are maintaining state for webCommands because it is a mutable object
// where it is possible to add new handlers. Therefor the state needs to be
// consistent everywhere it is called.
return this._webCommands.get();
}
private WebCommands createWebCommands() {
return new DefaultWebCommands();
}
@Override
public Application application() {
return this._application.get();
}
private Application createApplication() {
RequestFactory requestFactory = new DefaultRequestFactory(httpConfiguration());
SimpleInjector injector =
new SimpleInjector(NewInstanceInjector$.MODULE$, Map$.MODULE$.empty());
return new play.api.DefaultApplication(
environment().asScala(),
applicationLifecycle().asScala(),
injector,
configuration(),
requestFactory,
httpRequestHandler().asScala(),
scalaHttpErrorHandler(),
actorSystem(),
materializer(),
coordinatedShutdown())
.asJava();
}
@Override
public Langs langs() {
return this._langs.get();
}
private Langs createLangs() {
return new DefaultLangsProvider(configuration()).get().asJava();
}
@Override
public FileMimeTypes fileMimeTypes() {
return this._fileMimeTypes.get();
}
private FileMimeTypes createFileMimeTypes() {
return new DefaultFileMimeTypesProvider(httpConfiguration().fileMimeTypes()).get().asJava();
}
@Override
public MappedJavaHandlerComponents javaHandlerComponents() {
return this._javaHandlerComponents.get();
}
private MappedJavaHandlerComponents createJavaHandlerComponents() {
MappedJavaHandlerComponents javaHandlerComponents =
new MappedJavaHandlerComponents(
actionCreator(), httpConfiguration(), executionContext(), javaContextComponents());
return javaHandlerComponents
.addBodyParser(BodyParser.Default.class, this::defaultBodyParser)
.addBodyParser(BodyParser.AnyContent.class, this::anyContentBodyParser)
.addBodyParser(BodyParser.Json.class, this::jsonBodyParser)
.addBodyParser(BodyParser.TolerantJson.class, this::tolerantJsonBodyParser)
.addBodyParser(BodyParser.Xml.class, this::xmlBodyParser)
.addBodyParser(BodyParser.TolerantXml.class, this::tolerantXmlBodyParser)
.addBodyParser(BodyParser.Text.class, this::textBodyParser)
.addBodyParser(BodyParser.TolerantText.class, this::tolerantTextBodyParser)
.addBodyParser(BodyParser.Bytes.class, this::bytesBodyParser)
.addBodyParser(BodyParser.Raw.class, this::rawBodyParser)
.addBodyParser(BodyParser.FormUrlEncoded.class, this::formUrlEncodedBodyParser)
.addBodyParser(BodyParser.MultipartFormData.class, this::multipartFormDataBodyParser)
.addBodyParser(BodyParser.Empty.class, this::emptyBodyParser);
}
@Override
public HttpErrorHandler httpErrorHandler() {
return this._httpErrorHandler.get();
}
private HttpErrorHandler createHttpErrorHandler() {
return new DefaultHttpErrorHandler(
config(),
environment(),
new OptionalSourceMapper(OptionConverters.toScala(sourceMapper())),
() -> router().asScala());
}
@Override
public HttpRequestHandler httpRequestHandler() {
return this._httpRequestHandler.get();
}
private HttpRequestHandler createHttpRequestHandler() {
DefaultHttpFilters filters = new DefaultHttpFilters(httpFilters());
play.api.http.HttpErrorHandler scalaErrorHandler =
new JavaHttpErrorHandlerAdapter(httpErrorHandler());
return new JavaCompatibleHttpRequestHandler(
webCommands(),
new OptionalDevContext(OptionConverters.toScala(devContext())),
() -> router().asScala(),
scalaErrorHandler,
httpConfiguration(),
filters.asScala(),
javaHandlerComponents())
.asJava();
}
@Override
public ActorSystem actorSystem() {
return this._actorSystem.get();
}
private ActorSystem createActorSystem() {
return new ActorSystemProvider(environment().asScala(), configuration()).get();
}
@Override
public CoordinatedShutdown coordinatedShutdown() {
return this._coordinatedShutdown.get();
}
private CoordinatedShutdown createCoordinatedShutdown() {
return new CoordinatedShutdownProvider(actorSystem(), applicationLifecycle().asScala()).get();
}
@Override
public CookieSigner cookieSigner() {
return this._cookieSigner.get();
}
private CookieSigner createCookieSigner() {
play.api.libs.crypto.CookieSigner scalaCookieSigner =
new play.api.libs.crypto.DefaultCookieSigner(httpConfiguration().secret());
return new DefaultCookieSigner(scalaCookieSigner);
}
@Override
public CSRFTokenSigner csrfTokenSigner() {
return this._csrfTokenSigner.get();
}
private CSRFTokenSigner createCsrfTokenSigner() {
play.api.libs.crypto.CSRFTokenSigner scalaTokenSigner =
new play.api.libs.crypto.DefaultCSRFTokenSigner(cookieSigner().asScala(), clock());
return new DefaultCSRFTokenSigner(scalaTokenSigner);
}
@Override
public Files.TemporaryFileCreator tempFileCreator() {
return this._tempFileCreator.get();
}
private Files.TemporaryFileCreator createTempFileCreator() {
Configuration conf = configuration();
play.api.libs.Files.DefaultTemporaryFileReaper temporaryFileReaper =
new play.api.libs.Files.DefaultTemporaryFileReaper(
actorSystem(),
play.api.libs.Files.TemporaryFileReaperConfiguration$.MODULE$.fromConfiguration(conf));
return new play.api.libs.Files.DefaultTemporaryFileCreator(
applicationLifecycle().asScala(), temporaryFileReaper, conf)
.asJava();
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy