diff --git a/.gitignore b/.gitignore index 3097fb34..f4aa06b9 100644 --- a/.gitignore +++ b/.gitignore @@ -7,4 +7,5 @@ build/ *.prefs *.classpath *.prefs +*.factorypath bin/ diff --git a/README.md b/README.md index 1d68ee95..a2474d39 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,9 @@ +[![Discord](https://img.shields.io/discord/1074074312421683250?color=%237289da&label=discord)](https://discord.gg/Qcqf9R27BR) [![Build](https://github.com/avaje/avaje-jex/actions/workflows/build.yml/badge.svg)](https://github.com/avaje/avaje-jex/actions/workflows/build.yml) -[![Maven Central](https://img.shields.io/maven-central/v/io.avaje/avaje-jex-parent.svg?label=Maven%20Central)](https://mvnrepository.com/artifact/io.avaje/avaje-jex-parent) -[![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://github.com/avaje/avaje-jex/blob/master/LICENSE) [![JDK EA](https://github.com/avaje/avaje-jex/actions/workflows/jdk-ea.yml/badge.svg)](https://github.com/avaje/avaje-jex/actions/workflows/jdk-ea.yml) +[![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://github.com/avaje/avaje-jex/blob/master/LICENSE) +[![Maven Central](https://img.shields.io/maven-central/v/io.avaje/avaje-jex.svg?label=Maven%20Central)](https://mvnrepository.com/artifact/io.avaje/avaje-jex) +[![javadoc](https://javadoc.io/badge2/io.avaje/avaje-jex/javadoc.svg?color=purple)](https://javadoc.io/doc/io.avaje/avaje-jex) # avaje-jex diff --git a/avaje-jex-freemarker/src/main/java/io/avaje/jex/render/freemarker/FreeMarkerRender.java b/avaje-jex-freemarker/src/main/java/io/avaje/jex/render/freemarker/FreeMarkerRender.java index b9648228..67d4370a 100644 --- a/avaje-jex-freemarker/src/main/java/io/avaje/jex/render/freemarker/FreeMarkerRender.java +++ b/avaje-jex-freemarker/src/main/java/io/avaje/jex/render/freemarker/FreeMarkerRender.java @@ -10,7 +10,7 @@ import freemarker.template.TemplateException; import freemarker.template.Version; import io.avaje.jex.Context; -import io.avaje.jex.TemplateRender; +import io.avaje.jex.spi.TemplateRender; import io.avaje.spi.ServiceProvider; @ServiceProvider diff --git a/avaje-jex-mustache/src/main/java/io/avaje/jex/render/mustache/MustacheRender.java b/avaje-jex-mustache/src/main/java/io/avaje/jex/render/mustache/MustacheRender.java index 21d93700..f2aaf27c 100644 --- a/avaje-jex-mustache/src/main/java/io/avaje/jex/render/mustache/MustacheRender.java +++ b/avaje-jex-mustache/src/main/java/io/avaje/jex/render/mustache/MustacheRender.java @@ -3,7 +3,7 @@ import com.github.mustachejava.DefaultMustacheFactory; import com.github.mustachejava.MustacheFactory; import io.avaje.jex.Context; -import io.avaje.jex.TemplateRender; +import io.avaje.jex.spi.TemplateRender; import io.avaje.spi.ServiceProvider; import java.io.IOException; diff --git a/avaje-jex/src/main/java/io/avaje/jex/DJex.java b/avaje-jex/src/main/java/io/avaje/jex/DJex.java index 59fbfd20..3cd3a211 100644 --- a/avaje-jex/src/main/java/io/avaje/jex/DJex.java +++ b/avaje-jex/src/main/java/io/avaje/jex/DJex.java @@ -89,7 +89,7 @@ public Jex jsonService(JsonService jsonService) { } @Override - public Jex plugin(Plugin plugin) { + public Jex plugin(JexPlugin plugin) { plugin.apply(this); return this; } @@ -97,7 +97,7 @@ public Jex plugin(Plugin plugin) { @Override public Jex configureWith(BeanScope beanScope) { lifecycle.onShutdown(beanScope::close); - for (Plugin plugin : beanScope.list(Plugin.class)) { + for (JexPlugin plugin : beanScope.list(JexPlugin.class)) { plugin.apply(this); } for (ErrorHandling.Service service : beanScope.list(ErrorHandling.Service.class)) { diff --git a/avaje-jex/src/main/java/io/avaje/jex/DJexConfig.java b/avaje-jex/src/main/java/io/avaje/jex/DJexConfig.java index 536380c9..51fe8356 100644 --- a/avaje-jex/src/main/java/io/avaje/jex/DJexConfig.java +++ b/avaje-jex/src/main/java/io/avaje/jex/DJexConfig.java @@ -7,6 +7,7 @@ import javax.net.ssl.SSLContext; import io.avaje.jex.spi.JsonService; +import io.avaje.jex.spi.TemplateRender; class DJexConfig implements JexConfig { diff --git a/avaje-jex/src/main/java/io/avaje/jex/Jex.java b/avaje-jex/src/main/java/io/avaje/jex/Jex.java index ecb5fef6..a64824ba 100644 --- a/avaje-jex/src/main/java/io/avaje/jex/Jex.java +++ b/avaje-jex/src/main/java/io/avaje/jex/Jex.java @@ -2,6 +2,7 @@ import io.avaje.inject.BeanScope; import io.avaje.jex.spi.JsonService; +import io.avaje.jex.spi.TemplateRender; import java.util.Collection; import java.util.function.Consumer; @@ -97,7 +98,7 @@ static Jex create() { /** * Add Plugin functionality. */ - Jex plugin(Plugin plugin); + Jex plugin(JexPlugin plugin); /** * Configure given the dependency injection scope from avaje-inject. diff --git a/avaje-jex/src/main/java/io/avaje/jex/JexConfig.java b/avaje-jex/src/main/java/io/avaje/jex/JexConfig.java index f8815696..bbf3dbd1 100644 --- a/avaje-jex/src/main/java/io/avaje/jex/JexConfig.java +++ b/avaje-jex/src/main/java/io/avaje/jex/JexConfig.java @@ -7,6 +7,7 @@ import javax.net.ssl.SSLContext; import io.avaje.jex.spi.JsonService; +import io.avaje.jex.spi.TemplateRender; /** * Jex configuration. diff --git a/avaje-jex/src/main/java/io/avaje/jex/Plugin.java b/avaje-jex/src/main/java/io/avaje/jex/JexPlugin.java similarity index 86% rename from avaje-jex/src/main/java/io/avaje/jex/Plugin.java rename to avaje-jex/src/main/java/io/avaje/jex/JexPlugin.java index a9feb473..805402cb 100644 --- a/avaje-jex/src/main/java/io/avaje/jex/Plugin.java +++ b/avaje-jex/src/main/java/io/avaje/jex/JexPlugin.java @@ -3,7 +3,7 @@ /** * A plugin that can register things like routes, exception handlers etc. */ -public interface Plugin { +public interface JexPlugin { /** * Register the plugin features with jex. diff --git a/avaje-jex/src/main/java/io/avaje/jex/core/HealthPlugin.java b/avaje-jex/src/main/java/io/avaje/jex/core/HealthPlugin.java index 8ea2da11..6a84c555 100644 --- a/avaje-jex/src/main/java/io/avaje/jex/core/HealthPlugin.java +++ b/avaje-jex/src/main/java/io/avaje/jex/core/HealthPlugin.java @@ -3,13 +3,13 @@ import io.avaje.jex.AppLifecycle; import io.avaje.jex.Context; import io.avaje.jex.Jex; -import io.avaje.jex.Plugin; +import io.avaje.jex.JexPlugin; /** * Health plugin with liveness and readiness support based on * the application lifecycle support. */ -public class HealthPlugin implements Plugin { +public class HealthPlugin implements JexPlugin { private AppLifecycle lifecycle; diff --git a/avaje-jex/src/main/java/io/avaje/jex/core/TemplateManager.java b/avaje-jex/src/main/java/io/avaje/jex/core/TemplateManager.java index 11d7f51f..4de183ac 100644 --- a/avaje-jex/src/main/java/io/avaje/jex/core/TemplateManager.java +++ b/avaje-jex/src/main/java/io/avaje/jex/core/TemplateManager.java @@ -1,7 +1,7 @@ package io.avaje.jex.core; import io.avaje.jex.Context; -import io.avaje.jex.TemplateRender; +import io.avaje.jex.spi.TemplateRender; import java.util.HashMap; import java.util.HashSet; diff --git a/avaje-jex/src/main/java/io/avaje/jex/core/internal/CoreServiceLoader.java b/avaje-jex/src/main/java/io/avaje/jex/core/internal/CoreServiceLoader.java index e3ce91cb..14cd73b4 100644 --- a/avaje-jex/src/main/java/io/avaje/jex/core/internal/CoreServiceLoader.java +++ b/avaje-jex/src/main/java/io/avaje/jex/core/internal/CoreServiceLoader.java @@ -5,9 +5,9 @@ import java.util.Optional; import java.util.ServiceLoader; -import io.avaje.jex.TemplateRender; import io.avaje.jex.spi.JexExtension; import io.avaje.jex.spi.JsonService; +import io.avaje.jex.spi.TemplateRender; /** Core implementation of SpiServiceManager provided to specific implementations like jetty etc. */ class CoreServiceLoader { diff --git a/avaje-jex/src/main/java/io/avaje/jex/core/internal/CoreServiceManager.java b/avaje-jex/src/main/java/io/avaje/jex/core/internal/CoreServiceManager.java index 91f6a8e3..142cbef5 100644 --- a/avaje-jex/src/main/java/io/avaje/jex/core/internal/CoreServiceManager.java +++ b/avaje-jex/src/main/java/io/avaje/jex/core/internal/CoreServiceManager.java @@ -8,7 +8,7 @@ import io.avaje.jex.spi.HeaderKeys; import io.avaje.jex.spi.JsonService; import io.avaje.jex.spi.SpiContext; -import io.avaje.jex.spi.SpiServiceManager; +import io.avaje.jex.spi.TemplateRender; import java.io.UncheckedIOException; import java.io.UnsupportedEncodingException; @@ -20,7 +20,7 @@ /** * Core implementation of SpiServiceManager provided to specific implementations like jetty etc. */ -public class CoreServiceManager implements SpiServiceManager { +public final class CoreServiceManager implements SpiServiceManager { private static final System.Logger log = AppLog.getLogger("io.avaje.jex"); public static final String UTF_8 = "UTF-8"; diff --git a/avaje-jex/src/main/java/io/avaje/jex/spi/SpiServiceManager.java b/avaje-jex/src/main/java/io/avaje/jex/core/internal/SpiServiceManager.java similarity index 88% rename from avaje-jex/src/main/java/io/avaje/jex/spi/SpiServiceManager.java rename to avaje-jex/src/main/java/io/avaje/jex/core/internal/SpiServiceManager.java index 017f23ba..7eed68f8 100644 --- a/avaje-jex/src/main/java/io/avaje/jex/spi/SpiServiceManager.java +++ b/avaje-jex/src/main/java/io/avaje/jex/core/internal/SpiServiceManager.java @@ -1,7 +1,9 @@ -package io.avaje.jex.spi; +package io.avaje.jex.core.internal; import io.avaje.jex.Context; import io.avaje.jex.Routing; +import io.avaje.jex.jdk.CtxServiceManager; +import io.avaje.jex.spi.SpiContext; import java.util.Iterator; import java.util.List; @@ -11,7 +13,7 @@ /** * Core service methods available to Context implementations. */ -public interface SpiServiceManager { +public sealed interface SpiServiceManager permits CoreServiceManager, CtxServiceManager { /** * Read and return the type from json request content. diff --git a/avaje-jex/src/main/java/io/avaje/jex/http/HttpResponseException.java b/avaje-jex/src/main/java/io/avaje/jex/http/HttpResponseException.java index 1aef4859..7258f667 100644 --- a/avaje-jex/src/main/java/io/avaje/jex/http/HttpResponseException.java +++ b/avaje-jex/src/main/java/io/avaje/jex/http/HttpResponseException.java @@ -3,6 +3,10 @@ import java.util.Collections; import java.util.Map; +/** + * Throwing an uncaught {@code HttpResponseException} will interrupt http processing and set the + * status code and response body with the given message + */ public class HttpResponseException extends RuntimeException { private final int status; diff --git a/avaje-jex/src/main/java/io/avaje/jex/spi/ProxyServiceManager.java b/avaje-jex/src/main/java/io/avaje/jex/jdk/CtxServiceManager.java similarity index 67% rename from avaje-jex/src/main/java/io/avaje/jex/spi/ProxyServiceManager.java rename to avaje-jex/src/main/java/io/avaje/jex/jdk/CtxServiceManager.java index aeb80c02..68926fe0 100644 --- a/avaje-jex/src/main/java/io/avaje/jex/spi/ProxyServiceManager.java +++ b/avaje-jex/src/main/java/io/avaje/jex/jdk/CtxServiceManager.java @@ -1,25 +1,43 @@ -package io.avaje.jex.spi; +package io.avaje.jex.jdk; import io.avaje.jex.Context; import io.avaje.jex.Routing; +import io.avaje.jex.core.internal.SpiServiceManager; +import io.avaje.jex.spi.SpiContext; +import java.io.OutputStream; import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.stream.Stream; -/** - * Provides a delegating proxy to a SpiServiceManager. - *
- * Can be used by specific implementations like Jetty and JDK Http Server to add core functionality
- * to provide to the specific context implementation.
- */
-public abstract class ProxyServiceManager implements SpiServiceManager {
+public final class CtxServiceManager implements SpiServiceManager {
- protected final SpiServiceManager delegate;
+ private final String scheme;
+ private final String contextPath;
- protected ProxyServiceManager(SpiServiceManager delegate) {
+ private final SpiServiceManager delegate;
+
+ CtxServiceManager(SpiServiceManager delegate, String scheme, String contextPath) {
this.delegate = delegate;
+ this.scheme = scheme;
+ this.contextPath = contextPath;
+ }
+
+ OutputStream createOutputStream(JdkContext jdkContext) {
+ return new BufferedOutStream(jdkContext);
+ }
+
+ String scheme() {
+ return scheme;
+ }
+
+ public String url() {
+ return scheme + "://";
+ }
+
+ public String contextPath() {
+ return contextPath;
}
@Override
diff --git a/avaje-jex/src/main/java/io/avaje/jex/jdk/JdkContext.java b/avaje-jex/src/main/java/io/avaje/jex/jdk/JdkContext.java
index 7dd5ec6b..0b916450 100644
--- a/avaje-jex/src/main/java/io/avaje/jex/jdk/JdkContext.java
+++ b/avaje-jex/src/main/java/io/avaje/jex/jdk/JdkContext.java
@@ -39,7 +39,7 @@ class JdkContext implements Context, SpiContext {
private static final int SC_MOVED_TEMPORARILY = 302;
private static final String SET_COOKIE = "Set-Cookie";
private static final String COOKIE = "Cookie";
- private final ServiceManager mgr;
+ private final CtxServiceManager mgr;
private final String path;
private final Map