diff --git a/pippo-controller-parent/pippo-controller/pom.xml b/pippo-controller-parent/pippo-controller/pom.xml index 138df22b..5d1beb74 100644 --- a/pippo-controller-parent/pippo-controller/pom.xml +++ b/pippo-controller-parent/pippo-controller/pom.xml @@ -39,6 +39,14 @@ provided + + + javax.inject + javax.inject + 1 + provided + + junit diff --git a/pippo-controller-parent/pippo-controller/src/main/java/ro/pippo/controller/ControllerApplication.java b/pippo-controller-parent/pippo-controller/src/main/java/ro/pippo/controller/ControllerApplication.java index cb2891c0..6cb5dbc8 100644 --- a/pippo-controller-parent/pippo-controller/src/main/java/ro/pippo/controller/ControllerApplication.java +++ b/pippo-controller-parent/pippo-controller/src/main/java/ro/pippo/controller/ControllerApplication.java @@ -20,6 +20,9 @@ import ro.pippo.core.Application; import ro.pippo.core.PippoSettings; +import javax.inject.Inject; +import java.util.Optional; + /** * @author Decebal Suiu */ @@ -27,26 +30,28 @@ public class ControllerApplication extends Application { private static final Logger log = LoggerFactory.getLogger(ControllerApplication.class); - private ControllerRouteFactory controllerRouteFactory; + @Inject + private Optional controllerRouteFactory = Optional.empty(); public ControllerApplication() { super(); } + @Inject public ControllerApplication(PippoSettings settings) { super(settings); } public ControllerRouteFactory getControllerRouteFactory() { - if (controllerRouteFactory == null) { - controllerRouteFactory = new DefaultControllerRouteFactory().setContentTypeEngines(getContentTypeEngines()); + if (!controllerRouteFactory.isPresent()) { + controllerRouteFactory = Optional.of(new DefaultControllerRouteFactory().setContentTypeEngines(getContentTypeEngines())); } - return controllerRouteFactory; + return controllerRouteFactory.get(); } public ControllerApplication setControllerRouteFactory(ControllerRouteFactory controllerRouteFactory) { - this.controllerRouteFactory = controllerRouteFactory; + this.controllerRouteFactory = Optional.of(controllerRouteFactory); log.debug("Controller route factory is '{}'", controllerRouteFactory.getClass().getName()); return this; diff --git a/pippo-core/pom.xml b/pippo-core/pom.xml index 94b32333..63ef0479 100644 --- a/pippo-core/pom.xml +++ b/pippo-core/pom.xml @@ -29,6 +29,14 @@ ${slf4j.version} + + + javax.inject + javax.inject + 1 + provided + + junit diff --git a/pippo-core/src/main/java/ro/pippo/core/AbstractTemplateEngine.java b/pippo-core/src/main/java/ro/pippo/core/AbstractTemplateEngine.java index ddc15d04..3f76b260 100644 --- a/pippo-core/src/main/java/ro/pippo/core/AbstractTemplateEngine.java +++ b/pippo-core/src/main/java/ro/pippo/core/AbstractTemplateEngine.java @@ -20,6 +20,8 @@ import java.util.Locale; +import javax.inject.Inject; + /** * Convenience abstract implementation of {@link TemplateEngine}. * @@ -44,6 +46,7 @@ public abstract class AbstractTemplateEngine implements TemplateEngine { * and other settings for the initialization */ @Override + @Inject public final void init(Application application) { this.application = application; } diff --git a/pippo-core/src/main/java/ro/pippo/core/Application.java b/pippo-core/src/main/java/ro/pippo/core/Application.java index 421af8be..46ef54b3 100644 --- a/pippo-core/src/main/java/ro/pippo/core/Application.java +++ b/pippo-core/src/main/java/ro/pippo/core/Application.java @@ -37,11 +37,13 @@ import ro.pippo.core.websocket.WebSocketHandler; import ro.pippo.core.websocket.WebSocketRouter; +import javax.inject.Inject; import javax.servlet.ServletContext; -import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.Objects; +import java.util.Optional; /** * Base class for all Pippo applications. @@ -54,52 +56,67 @@ public class Application implements ResourceRouting { private static final Logger log = LoggerFactory.getLogger(Application.class); - private PippoSettings pippoSettings; - private Languages languages; - private Messages messages; - private MimeTypes mimeTypes; - private HttpCacheToolkit httpCacheToolkit; - private TemplateEngine templateEngine; - private ContentTypeEngines engines; - private EntityRequestEngine entityRequestEngine; - protected Router router; - private ErrorHandler errorHandler; - private RequestResponseFactory requestResponseFactory; - private ServletContext servletContext; + @Inject + private Optional languages = Optional.empty(); - private List initializers; + @Inject + private Optional messages = Optional.empty(); - private RoutePreDispatchListenerList routePreDispatchListeners; - private RoutePostDispatchListenerList routePostDispatchListeners; + @Inject + private Optional mimeTypes = Optional.empty(); - private Map locals; - private RouteHandler notFoundRouteHandler; + @Inject + private Optional httpCacheToolkit = Optional.empty(); + + @Inject + private Optional engines = Optional.empty(); + + @Inject + private Optional entityRequestEngine = Optional.empty(); + + @Inject + private Optional requestResponseFactory = Optional.empty(); + + @Inject + private Optional> initializers = Optional.empty(); + + @Inject + private Optional routePreDispatchListeners = Optional.empty(); + + @Inject + private Optional routePostDispatchListeners = Optional.empty(); + + @Inject + private Optional webSocketRouter = Optional.empty(); - private WebSocketRouter webSocketRouter; + @Inject + private Optional templateEngine = Optional.empty(); + + @Inject + private Optional> notFoundRouteHandler = Optional.empty(); + + @Inject + private Optional router = Optional.empty(); + + @Inject + private Optional errorHandler = Optional.empty(); + + private PippoSettings pippoSettings; + private ServletContext servletContext; + private Map locals; public Application() { this(new PippoSettings(RuntimeMode.getCurrent())); } + @Inject public Application(PippoSettings settings) { - this.pippoSettings = settings; - this.languages = new Languages(settings); - this.messages = new Messages(languages); - this.mimeTypes = new MimeTypes(settings); - this.httpCacheToolkit = new HttpCacheToolkit(settings); - this.engines = new ContentTypeEngines(); - this.initializers = new ArrayList<>(); - this.webSocketRouter = new WebSocketRouter(); - - registerContentTypeEngine(TextPlainEngine.class); + pippoSettings = settings; } public final void init() { - // add initializers - initializers.addAll(ServiceLocator.locateAll(Initializer.class)); - // call each initializer - for (Initializer initializer : initializers) { + for (Initializer initializer : getInitializers()) { log.debug("Initializing '{}'", initializer.getClass().getName()); try { initializer.init(this); @@ -122,7 +139,7 @@ public final void init() { public final void destroy() { onDestroy(); - for (Initializer initializer : initializers) { + for (Initializer initializer : getInitializers()) { log.debug("Destroying '{}'", initializer.getClass().getName()); try { initializer.destroy(this); @@ -142,35 +159,55 @@ protected void onDestroy() { * The runtime mode. Must currently be either DEV, TEST, or PROD. */ public RuntimeMode getRuntimeMode() { - return pippoSettings.getRuntimeMode(); + return getPippoSettings().getRuntimeMode(); } public PippoSettings getPippoSettings() { + if (pippoSettings == null) { + pippoSettings = new PippoSettings(RuntimeMode.getCurrent()); + } + return pippoSettings; } public String getApplicationName() { - return pippoSettings.getString(PippoConstants.SETTING_APPLICATION_NAME, ""); + return getPippoSettings().getString(PippoConstants.SETTING_APPLICATION_NAME, ""); } public String getApplicationVersion() { - return pippoSettings.getString(PippoConstants.SETTING_APPLICATION_VERSION, ""); + return getPippoSettings().getString(PippoConstants.SETTING_APPLICATION_VERSION, ""); } public Languages getLanguages() { - return languages; + if (!languages.isPresent()) { + languages = Optional.of(new Languages(getPippoSettings())); + } + + return languages.get(); } public Messages getMessages() { - return messages; + if (!messages.isPresent()) { + messages = Optional.of(new Messages(getLanguages())); + } + + return messages.get(); } public MimeTypes getMimeTypes() { - return mimeTypes; + if (!mimeTypes.isPresent()) { + mimeTypes = Optional.of(new MimeTypes(getPippoSettings())); + } + + return mimeTypes.get(); } public HttpCacheToolkit getHttpCacheToolkit() { - return httpCacheToolkit; + if (!httpCacheToolkit.isPresent()) { + httpCacheToolkit = Optional.of(new HttpCacheToolkit(getPippoSettings())); + } + + return httpCacheToolkit.get(); } /** @@ -179,7 +216,7 @@ public HttpCacheToolkit getHttpCacheToolkit() { * @param engineClass */ public void registerTemplateEngine(Class engineClass) { - if (templateEngine != null) { + if (templateEngine.isPresent()) { log.debug("Template engine already registered, ignoring '{}'", engineClass.getName()); return; } @@ -193,52 +230,57 @@ public void registerTemplateEngine(Class engineClass) } public TemplateEngine getTemplateEngine() { - return templateEngine; + return templateEngine.orElse(null); } public void setTemplateEngine(TemplateEngine templateEngine) { templateEngine.init(this); - this.templateEngine = templateEngine; + this.templateEngine = Optional.of(templateEngine); log.debug("Template engine is '{}'", templateEngine.getClass().getName()); } public ContentTypeEngines getContentTypeEngines() { - return engines; + if (!engines.isPresent()) { + engines = Optional.of(new ContentTypeEngines()); + registerContentTypeEngine(TextPlainEngine.class); + } + + return engines.get(); } public boolean hasContentTypeEngine(String contentType) { - return engines.hasContentTypeEngine(contentType); + return getContentTypeEngines().hasContentTypeEngine(contentType); } public void registerContentTypeEngine(Class engineClass) { - ContentTypeEngine engine = engines.registerContentTypeEngine(engineClass); + ContentTypeEngine engine = getContentTypeEngines().registerContentTypeEngine(engineClass); if (engine != null) { engine.init(this); } } public ContentTypeEngine getContentTypeEngine(String contentType) { - return engines.getContentTypeEngine(contentType); + return getContentTypeEngines().getContentTypeEngine(contentType); } public EntityRequestEngine getEntityRequestEngine() { - if (entityRequestEngine == null) { - entityRequestEngine = new DefaultEntityRequestEngine(getContentTypeEngines()); + if (!entityRequestEngine.isPresent()) { + entityRequestEngine = Optional.of(new DefaultEntityRequestEngine(getContentTypeEngines())); } - return entityRequestEngine; + return entityRequestEngine.get(); } public void setEntityRequestEngine(EntityRequestEngine entityRequestEngine) { - this.entityRequestEngine = entityRequestEngine; + this.entityRequestEngine = Optional.of(entityRequestEngine); } public Router getRouter() { - if (router == null) { - router = new DefaultRouter(); + if (!router.isPresent()) { + router = Optional.of(new DefaultRouter()); } - return router; + return router.get(); } public void setRouter(Router router) { @@ -246,13 +288,14 @@ public void setRouter(Router router) { } public void setRouter(Router router, boolean preserveOldTransformers) { - if (preserveOldTransformers && (router != null)) { + Objects.requireNonNull(router); + if (preserveOldTransformers) { // preserve route transformers already registered - List transformers = this.router.getRouteTransformers(); + List transformers = getRouter().getRouteTransformers(); transformers.forEach(router::addRouteTransformer); } - this.router = router; + this.router = Optional.of(router); } @Override @@ -266,23 +309,23 @@ public void addRouteGroup(RouteGroup routeGroup) { } public ErrorHandler getErrorHandler() { - if (errorHandler == null) { - errorHandler = new DefaultErrorHandler(this); + if (!errorHandler.isPresent()) { + errorHandler = Optional.of(new DefaultErrorHandler(this)); } - return errorHandler; + return errorHandler.get(); } public void setErrorHandler(ErrorHandler errorHandler) { - this.errorHandler = errorHandler; + this.errorHandler = Optional.of(errorHandler); } public final RequestResponseFactory getRequestResponseFactory() { - if (requestResponseFactory == null) { - requestResponseFactory = createRequestResponseFactory(); + if (!requestResponseFactory.isPresent()) { + requestResponseFactory = Optional.of(createRequestResponseFactory()); } - return requestResponseFactory; + return requestResponseFactory.get(); } /** @@ -296,19 +339,19 @@ protected RequestResponseFactory createRequestResponseFactory() { } public RoutePreDispatchListenerList getRoutePreDispatchListeners() { - if (routePreDispatchListeners == null) { - routePreDispatchListeners = new RoutePreDispatchListenerList(); + if (!routePreDispatchListeners.isPresent()) { + routePreDispatchListeners = Optional.of(new RoutePreDispatchListenerList()); } - return routePreDispatchListeners; + return routePreDispatchListeners.get(); } public RoutePostDispatchListenerList getRoutePostDispatchListeners() { - if (routePostDispatchListeners == null) { - routePostDispatchListeners = new RoutePostDispatchListenerList(); + if (!routePostDispatchListeners.isPresent()) { + routePostDispatchListeners = Optional.of(new RoutePostDispatchListenerList()); } - return routePostDispatchListeners; + return routePostDispatchListeners.get(); } public Map getLocals() { @@ -349,8 +392,8 @@ public void addRouteTransformer(RouteTransformer transformer) { * * @param routeHandler */ - public void setNotFoundRouteHandler(RouteHandler routeHandler) { - this.notFoundRouteHandler = routeHandler; + public void setNotFoundRouteHandler(RouteHandler routeHandler) { + this.notFoundRouteHandler = Optional.of(routeHandler); } /** @@ -358,22 +401,34 @@ public void setNotFoundRouteHandler(RouteHandler routeHandler) { * * @return */ - public RouteHandler getNotFoundRouteHandler() { - return notFoundRouteHandler; + public RouteHandler getNotFoundRouteHandler() { + return notFoundRouteHandler.orElse(null); } public void addWebSocket(String uriPattern, WebSocketHandler webSocketHandler) { - webSocketRouter.addRoute(uriPattern, webSocketHandler); + getWebSocketRouter().addRoute(uriPattern, webSocketHandler); } public WebSocketRouter getWebSocketRouter() { - return webSocketRouter; + if (!webSocketRouter.isPresent()) { + webSocketRouter = Optional.of(new WebSocketRouter()); + } + + return webSocketRouter.get(); + } + + public List getInitializers() { + if (!initializers.isPresent()) { + initializers = Optional.of(ServiceLocator.locateAll(Initializer.class)); + } + + return initializers.get(); } /** * Returns not null only in the context of the web layer (on a HTTP request). * It cannot be useful in a service (server side business layer). - * For example if want to have access to PippoSettings from a service you must to inject PippoSettings + * For example if you want to have access to PippoSettings from a service you must inject PippoSettings * in that service and not to use Application.get().getPippoSettings(). * * @return The application instance or null diff --git a/pippo-core/src/main/java/ro/pippo/core/Languages.java b/pippo-core/src/main/java/ro/pippo/core/Languages.java index cd206052..85f238ed 100644 --- a/pippo-core/src/main/java/ro/pippo/core/Languages.java +++ b/pippo-core/src/main/java/ro/pippo/core/Languages.java @@ -20,6 +20,7 @@ import ro.pippo.core.route.RouteContext; import ro.pippo.core.util.StringUtils; +import javax.inject.Inject; import javax.servlet.http.Cookie; import java.util.List; import java.util.Locale; @@ -48,6 +49,7 @@ public class Languages { private final Map languageLookup; + @Inject public Languages(PippoSettings pippoSettings) { this.pippoSettings = pippoSettings; diff --git a/pippo-core/src/main/java/ro/pippo/core/Messages.java b/pippo-core/src/main/java/ro/pippo/core/Messages.java index 3b7cf828..d41405f7 100644 --- a/pippo-core/src/main/java/ro/pippo/core/Messages.java +++ b/pippo-core/src/main/java/ro/pippo/core/Messages.java @@ -21,6 +21,7 @@ import ro.pippo.core.util.ClasspathUtils; import ro.pippo.core.util.StringUtils; +import javax.inject.Inject; import java.io.IOException; import java.io.InputStreamReader; import java.net.URL; @@ -51,6 +52,7 @@ public class Messages { private final Languages languages; + @Inject public Messages(Languages languages) { this.languages = languages; this.languageMessages = loadRegisteredMessageResources(); diff --git a/pippo-core/src/main/java/ro/pippo/core/Pippo.java b/pippo-core/src/main/java/ro/pippo/core/Pippo.java index c991c52a..1ac0dd53 100644 --- a/pippo-core/src/main/java/ro/pippo/core/Pippo.java +++ b/pippo-core/src/main/java/ro/pippo/core/Pippo.java @@ -24,6 +24,7 @@ import ro.pippo.core.route.RouteGroup; import ro.pippo.core.util.ServiceLocator; +import javax.inject.Inject; import java.io.File; import java.io.IOException; import java.io.InputStream; @@ -50,6 +51,7 @@ public Pippo() { addShutdownHook(); } + @Inject public Pippo(Application application) { this.application = application; log.debug("Application '{}'", application); @@ -130,6 +132,7 @@ public WebServer getServer() { * @param server * @return */ + @Inject public Pippo setServer(WebServer server) { this.server = server; this.server.init(getApplication()); diff --git a/pippo-core/src/main/java/ro/pippo/core/PippoSettings.java b/pippo-core/src/main/java/ro/pippo/core/PippoSettings.java index acea7b11..a272bb0f 100644 --- a/pippo-core/src/main/java/ro/pippo/core/PippoSettings.java +++ b/pippo-core/src/main/java/ro/pippo/core/PippoSettings.java @@ -105,6 +105,10 @@ public class PippoSettings { private volatile long lastModified; + public PippoSettings() { + this(RuntimeMode.getCurrent()); + } + public PippoSettings(RuntimeMode runtimeMode) { this.runtimeMode = runtimeMode; this.propertiesUrl = getPropertiesUrl(); diff --git a/pippo-core/src/main/java/ro/pippo/core/util/HttpCacheToolkit.java b/pippo-core/src/main/java/ro/pippo/core/util/HttpCacheToolkit.java index 464ee0f4..6aabe172 100644 --- a/pippo-core/src/main/java/ro/pippo/core/util/HttpCacheToolkit.java +++ b/pippo-core/src/main/java/ro/pippo/core/util/HttpCacheToolkit.java @@ -22,6 +22,7 @@ import ro.pippo.core.PippoSettings; import ro.pippo.core.route.RouteContext; +import javax.inject.Inject; import java.text.ParseException; import java.util.Date; @@ -34,6 +35,7 @@ public class HttpCacheToolkit { private final PippoSettings pippoSettings; + @Inject public HttpCacheToolkit(PippoSettings pippoSettings) { this.pippoSettings = pippoSettings; } diff --git a/pippo-core/src/main/java/ro/pippo/core/util/MimeTypes.java b/pippo-core/src/main/java/ro/pippo/core/util/MimeTypes.java index 746a6a49..b2ae0574 100644 --- a/pippo-core/src/main/java/ro/pippo/core/util/MimeTypes.java +++ b/pippo-core/src/main/java/ro/pippo/core/util/MimeTypes.java @@ -20,6 +20,7 @@ import ro.pippo.core.PippoConstants; import ro.pippo.core.PippoSettings; +import javax.inject.Inject; import java.io.InputStream; import java.net.URL; import java.util.List; @@ -39,6 +40,7 @@ public class MimeTypes { private final PippoSettings pippoSettings; + @Inject public MimeTypes(PippoSettings pippoSettings) { this.pippoSettings = pippoSettings; this.extPattern = Pattern.compile("^.*\\.([^.]+)$");