add htmlflow, add utility methods to HtmlTemplateResource
This commit is contained in:
parent
c5da201308
commit
3952de7e78
12 changed files with 260 additions and 24 deletions
4
net-http-htmlflow/build.gradle
Normal file
4
net-http-htmlflow/build.gradle
Normal file
|
@ -0,0 +1,4 @@
|
|||
dependencies {
|
||||
api project(':net-http-server')
|
||||
api libs.htmlflow
|
||||
}
|
8
net-http-htmlflow/src/main/java/module-info.java
Normal file
8
net-http-htmlflow/src/main/java/module-info.java
Normal file
|
@ -0,0 +1,8 @@
|
|||
module org.xbib.net.http.htmlflow {
|
||||
exports org.xbib.net.http.htmlflow;
|
||||
requires org.xbib.net;
|
||||
requires org.xbib.net.http;
|
||||
requires org.xbib.net.http.server;
|
||||
requires org.xbib.config;
|
||||
requires java.logging;
|
||||
}
|
|
@ -0,0 +1,60 @@
|
|||
package org.xbib.net.http.htmlflow;
|
||||
|
||||
import org.xbib.net.Attributes;
|
||||
import org.xbib.net.Resource;
|
||||
import org.xbib.net.buffer.DataBuffer;
|
||||
import org.xbib.net.http.HttpResponseStatus;
|
||||
import org.xbib.net.http.server.application.Application;
|
||||
import org.xbib.net.http.server.resource.HtmlTemplateResource;
|
||||
import org.xbib.net.http.server.resource.HtmlTemplateResourceHandler;
|
||||
import org.xbib.net.http.server.route.HttpRouterContext;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.nio.file.Path;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import static org.xbib.net.http.HttpHeaderNames.CONTENT_TYPE;
|
||||
|
||||
public class HtmlFlowResourceHandler extends HtmlTemplateResourceHandler {
|
||||
|
||||
public HtmlFlowResourceHandler(Path root, String suffix, String indexFileName) {
|
||||
super(root, suffix, indexFileName);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Resource createResource(HttpRouterContext httpRouterContext) throws IOException {
|
||||
return new HtmlFlowResource(this, httpRouterContext);
|
||||
}
|
||||
|
||||
protected static class HtmlFlowResource extends HtmlTemplateResource {
|
||||
|
||||
private static final Logger logger = Logger.getLogger(HtmlFlowResource.class.getName());
|
||||
|
||||
protected HtmlFlowResource(HtmlTemplateResourceHandler templateResourceHandler, HttpRouterContext httpRouterContext) throws IOException {
|
||||
super(templateResourceHandler, httpRouterContext);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void render(HttpRouterContext context) throws IOException {
|
||||
Application application = context.getAttributes().get(Application.class, "application");
|
||||
if (application == null) {
|
||||
logger.log(Level.WARNING, "application is null");
|
||||
return;
|
||||
}
|
||||
DataBuffer dataBuffer = context.getDataBufferFactory().allocateBuffer();
|
||||
dataBuffer.write(render(application, context.getAttributes()), StandardCharsets.UTF_8);
|
||||
HttpResponseStatus httpResponseStatus = context.getAttributes().get(HttpResponseStatus.class, "_status", HttpResponseStatus.OK);
|
||||
context.status(httpResponseStatus)
|
||||
.header("cache-control", "no-cache") // override default must-revalidate behavior
|
||||
.header("content-length", Integer.toString(dataBuffer.writePosition()))
|
||||
.header(CONTENT_TYPE, "text/html; charset=" + StandardCharsets.UTF_8.displayName())
|
||||
.body(dataBuffer);
|
||||
}
|
||||
|
||||
protected String render(Application application, Attributes attributes) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,15 @@
|
|||
package org.xbib.net.http.htmlflow;
|
||||
|
||||
import org.xbib.net.http.server.service.BaseHttpService;
|
||||
import org.xbib.net.http.server.service.BaseHttpServiceBuilder;
|
||||
|
||||
public class HtmlFlowService extends BaseHttpService {
|
||||
|
||||
protected HtmlFlowService(BaseHttpServiceBuilder builder) {
|
||||
super(builder);
|
||||
}
|
||||
|
||||
public static HtmlFlowServiceBuilder builder() {
|
||||
return new HtmlFlowServiceBuilder();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,69 @@
|
|||
package org.xbib.net.http.htmlflow;
|
||||
|
||||
import org.xbib.net.ParameterDefinition;
|
||||
import org.xbib.net.http.HttpMethod;
|
||||
import org.xbib.net.http.server.HttpHandler;
|
||||
import org.xbib.net.http.server.domain.HttpSecurityDomain;
|
||||
import org.xbib.net.http.server.service.BaseHttpServiceBuilder;
|
||||
|
||||
import java.nio.file.Path;
|
||||
|
||||
public class HtmlFlowServiceBuilder extends BaseHttpServiceBuilder {
|
||||
|
||||
protected Path prefix;
|
||||
|
||||
protected String suffix;
|
||||
|
||||
public HtmlFlowServiceBuilder() {
|
||||
super();
|
||||
this.prefix = null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public HtmlFlowServiceBuilder setPath(String path) {
|
||||
super.setPath(path);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public HtmlFlowServiceBuilder setMethod(HttpMethod... httpMethod) {
|
||||
super.setMethod(httpMethod);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public HtmlFlowServiceBuilder setHandler(HttpHandler... handler) {
|
||||
super.setHandler(handler);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public HtmlFlowServiceBuilder setParameterDefinition(ParameterDefinition... parameterDefinition) {
|
||||
super.setParameterDefinition(parameterDefinition);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public HtmlFlowServiceBuilder setSecurityDomain(HttpSecurityDomain securityDomain) {
|
||||
super.setSecurityDomain(securityDomain);
|
||||
return this;
|
||||
}
|
||||
|
||||
public HtmlFlowServiceBuilder setPrefix(Path prefix) {
|
||||
this.prefix = prefix;
|
||||
return this;
|
||||
}
|
||||
|
||||
public HtmlFlowServiceBuilder setSuffix(String suffix) {
|
||||
this.suffix = suffix;
|
||||
return this;
|
||||
}
|
||||
|
||||
public HtmlFlowService build() {
|
||||
if (this.handlers == null) {
|
||||
HttpHandler httpHandler = new HtmlFlowResourceHandler(prefix, suffix, "index.java");
|
||||
setHandler(httpHandler);
|
||||
}
|
||||
return new HtmlFlowService(this);
|
||||
}
|
||||
}
|
|
@ -1,10 +1,9 @@
|
|||
package org.xbib.net.http.j2html;
|
||||
|
||||
import org.xbib.net.Attributes;
|
||||
import org.xbib.net.Resource;
|
||||
import org.xbib.net.buffer.DataBuffer;
|
||||
import org.xbib.net.http.HttpResponseStatus;
|
||||
import org.xbib.net.http.server.application.Application;
|
||||
import org.xbib.net.http.server.HttpRequest;
|
||||
import org.xbib.net.http.server.resource.HtmlTemplateResource;
|
||||
import org.xbib.net.http.server.resource.HtmlTemplateResourceHandler;
|
||||
import org.xbib.net.http.server.route.HttpRouterContext;
|
||||
|
@ -12,8 +11,7 @@ import org.xbib.net.http.server.route.HttpRouterContext;
|
|||
import java.io.IOException;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.nio.file.Path;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
import java.util.Objects;
|
||||
|
||||
import static j2html.TagCreator.body;
|
||||
import static j2html.TagCreator.h1;
|
||||
|
@ -36,22 +34,24 @@ public class J2HtmlResourceHandler extends HtmlTemplateResourceHandler {
|
|||
|
||||
protected static class J2HtmlResource extends HtmlTemplateResource {
|
||||
|
||||
private static final Logger logger = Logger.getLogger(J2HtmlResource.class.getName());
|
||||
protected HttpRequest request;
|
||||
|
||||
protected J2HtmlResource(HtmlTemplateResourceHandler templateResourceHandler, HttpRouterContext httpRouterContext) throws IOException {
|
||||
protected J2HtmlResource(HtmlTemplateResourceHandler templateResourceHandler,
|
||||
HttpRouterContext httpRouterContext) throws IOException {
|
||||
super(templateResourceHandler, httpRouterContext);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void render(HttpRouterContext context) throws IOException {
|
||||
Application application = context.getAttributes().get(Application.class, "application");
|
||||
if (application == null) {
|
||||
logger.log(Level.WARNING, "application is null");
|
||||
return;
|
||||
}
|
||||
this.request = context.getRequest();
|
||||
Objects.requireNonNull(responseBuilder);
|
||||
DataBuffer dataBuffer = context.getDataBufferFactory().allocateBuffer();
|
||||
dataBuffer.write(render(application, context.getAttributes()), StandardCharsets.UTF_8);
|
||||
HttpResponseStatus httpResponseStatus = context.getAttributes().get(HttpResponseStatus.class, "_status", HttpResponseStatus.OK);
|
||||
dataBuffer.write(renderBody(context), StandardCharsets.UTF_8);
|
||||
HttpResponseStatus httpResponseStatus = responseBuilder.getResponseStatus();
|
||||
if (httpResponseStatus == null) {
|
||||
httpResponseStatus = HttpResponseStatus.OK;
|
||||
}
|
||||
//context.getAttributes().get(HttpResponseStatus.class, "_status", HttpResponseStatus.OK);
|
||||
context.status(httpResponseStatus)
|
||||
.header("cache-control", "no-cache") // override default must-revalidate behavior
|
||||
.header("content-length", Integer.toString(dataBuffer.writePosition()))
|
||||
|
@ -59,7 +59,7 @@ public class J2HtmlResourceHandler extends HtmlTemplateResourceHandler {
|
|||
.body(dataBuffer);
|
||||
}
|
||||
|
||||
protected String render(Application application, Attributes attributes) {
|
||||
protected String renderBody(HttpRouterContext context) {
|
||||
return body(
|
||||
h1("Hello World")
|
||||
).render();
|
||||
|
|
|
@ -5,6 +5,7 @@ dependencies {
|
|||
api project(':net-http-server-application-config')
|
||||
api project(':net-http-template-groovy')
|
||||
api project(':net-http-j2html')
|
||||
api project(':net-http-htmlflow')
|
||||
api libs.jdbc.query
|
||||
implementation libs.webjars.bootstrap
|
||||
implementation libs.webjars.jquery
|
||||
|
|
|
@ -197,7 +197,6 @@ public final class Bootstrap {
|
|||
return 0;
|
||||
}
|
||||
|
||||
|
||||
private static final String hexFavIcon =
|
||||
"000001000100101000000100200068040000160000002800000010000000" +
|
||||
"200000000100200000000000000000000000000000000000000000000000" +
|
||||
|
|
|
@ -3,7 +3,6 @@ package org.xbib.net.http.server.application.web.j2html;
|
|||
import org.xbib.net.Attributes;
|
||||
import org.xbib.net.Resource;
|
||||
import org.xbib.net.http.j2html.J2HtmlResourceHandler;
|
||||
import org.xbib.net.http.server.application.Application;
|
||||
import org.xbib.net.http.server.resource.HtmlTemplateResourceHandler;
|
||||
import org.xbib.net.http.server.route.HttpRouterContext;
|
||||
import org.xbib.net.util.ExceptionFormatter;
|
||||
|
@ -30,7 +29,8 @@ public class InternalServerErrorHandler extends J2HtmlResourceHandler {
|
|||
}
|
||||
|
||||
@Override
|
||||
protected String render(Application application, Attributes attributes) {
|
||||
protected String renderBody(HttpRouterContext httpRouterContext) {
|
||||
Attributes attributes = httpRouterContext.getAttributes();
|
||||
String message = attributes.get(String.class, "_message");
|
||||
Throwable throwable = attributes.get(Throwable.class, "_throwable");
|
||||
String stackTrace = ExceptionFormatter.format(throwable);
|
||||
|
|
|
@ -13,6 +13,7 @@ import java.util.Map;
|
|||
import java.util.Set;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import org.xbib.net.http.HttpAddress;
|
||||
import org.xbib.net.http.cookie.SameSite;
|
||||
import org.xbib.net.http.server.route.BaseHttpRouterContext;
|
||||
|
|
|
@ -4,9 +4,14 @@ import java.io.IOException;
|
|||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.time.Instant;
|
||||
import java.util.Objects;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
import org.xbib.net.URL;
|
||||
import org.xbib.net.http.HttpHeaderNames;
|
||||
import org.xbib.net.http.HttpResponseStatus;
|
||||
import org.xbib.net.http.server.HttpRequest;
|
||||
import org.xbib.net.http.server.HttpResponseBuilder;
|
||||
import org.xbib.net.http.server.route.HttpRouterContext;
|
||||
import org.xbib.net.http.server.application.Application;
|
||||
|
||||
|
@ -40,12 +45,18 @@ public class HtmlTemplateResource implements HttpServerResource {
|
|||
|
||||
protected final boolean negotiateLocale;
|
||||
|
||||
protected final HttpResponseBuilder responseBuilder;
|
||||
|
||||
protected final Application application;
|
||||
|
||||
protected HtmlTemplateResource(HtmlTemplateResourceHandler templateResourceHandler,
|
||||
HttpRouterContext httpRouterContext) throws IOException {
|
||||
this.templateResourceHandler = templateResourceHandler;
|
||||
String indexFileName = templateResourceHandler.getIndexFileName();
|
||||
Application application = httpRouterContext.getAttributes().get(Application.class, "application");
|
||||
this.application = httpRouterContext.getAttributes().get(Application.class, "application");
|
||||
Objects.requireNonNull(application);
|
||||
this.negotiateLocale = application.getSettings().getAsBoolean("negotiateLocale", false);
|
||||
this.responseBuilder = httpRouterContext.getAttributes().get(HttpResponseBuilder.class, "response");
|
||||
Objects.requireNonNull(responseBuilder);
|
||||
Path root = templateResourceHandler.getRoot();
|
||||
root = root != null ? root : application.getHome();
|
||||
if (root == null) {
|
||||
|
@ -57,13 +68,13 @@ public class HtmlTemplateResource implements HttpServerResource {
|
|||
" root = " + root +
|
||||
" resource path = " + resourcePath +
|
||||
" path = " + path +
|
||||
" index file name = " + indexFileName);
|
||||
" index file name = " + templateResourceHandler.getIndexFileName());
|
||||
this.name = path.getFileName().toString();
|
||||
this.baseName = AbstractResourceHandler.basename(name);
|
||||
this.suffix = AbstractResourceHandler.suffix(name);
|
||||
if (Files.isDirectory(path)) {
|
||||
if (getIndexFileName() != null) {
|
||||
Path indexPath = path.resolve(indexFileName);
|
||||
Path indexPath = path.resolve(templateResourceHandler.getIndexFileName());
|
||||
logger.log(Level.FINEST, "resolved to index path = " + indexPath);
|
||||
if (Files.exists(indexPath)) {
|
||||
logger.log(Level.FINEST, "index path exists");
|
||||
|
@ -137,7 +148,7 @@ public class HtmlTemplateResource implements HttpServerResource {
|
|||
|
||||
@Override
|
||||
public String getIndexFileName() {
|
||||
return templateResourceHandler.getIndexFileName();
|
||||
return templateResourceHandler != null ? templateResourceHandler.getIndexFileName() : null;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -163,11 +174,77 @@ public class HtmlTemplateResource implements HttpServerResource {
|
|||
",lastmodified=" + lastModified +
|
||||
",length=" + length +
|
||||
",isExists=" + isExists +
|
||||
",isDirectory=" + isDirectory() + "]";
|
||||
",isDirectory=" + isDirectory + "]";
|
||||
}
|
||||
|
||||
@Override
|
||||
public void render(HttpRouterContext httpRouterContext) throws IOException {
|
||||
// to be overriden
|
||||
}
|
||||
|
||||
public String contextPath(HttpRequest request, String rel) {
|
||||
return url(request, rel, false);
|
||||
}
|
||||
|
||||
public String url(HttpRequest request, String rel) {
|
||||
return url(request, rel, true);
|
||||
}
|
||||
|
||||
public String url(HttpRequest request, String rel, boolean absolute) {
|
||||
String prefix = application.getSettings().get("web.prefix", "/");
|
||||
if (!prefix.endsWith("/")) {
|
||||
prefix = prefix + "/";
|
||||
}
|
||||
URL url = request.getServerURL().resolve(prefix).resolve(rel);
|
||||
return absolute ? url.toExternalForm() : toOrigin(url);
|
||||
}
|
||||
|
||||
public void setResponseStatus(HttpResponseStatus responseStatus) {
|
||||
this.responseBuilder.setResponseStatus(responseStatus);
|
||||
}
|
||||
|
||||
public void movedPermanently(String url) {
|
||||
this.responseBuilder.setResponseStatus(HttpResponseStatus.MOVED_PERMANENTLY);
|
||||
this.responseBuilder.setHeader(HttpHeaderNames.LOCATION, url);
|
||||
}
|
||||
|
||||
public void found(String url) {
|
||||
this.responseBuilder.setResponseStatus(HttpResponseStatus.FOUND);
|
||||
this.responseBuilder.setHeader(HttpHeaderNames.LOCATION, url);
|
||||
}
|
||||
|
||||
public void seeOther(String url) {
|
||||
this.responseBuilder.setResponseStatus(HttpResponseStatus.SEE_OTHER);
|
||||
this.responseBuilder.setHeader(HttpHeaderNames.LOCATION, url);
|
||||
}
|
||||
|
||||
public void temporaryRedirect(String url) {
|
||||
this.responseBuilder.setResponseStatus(HttpResponseStatus.TEMPORARY_REDIRECT);
|
||||
this.responseBuilder.setHeader(HttpHeaderNames.LOCATION, url);
|
||||
}
|
||||
|
||||
public void notFound() {
|
||||
this.responseBuilder.setResponseStatus(HttpResponseStatus.NOT_FOUND);
|
||||
}
|
||||
|
||||
public void gone() {
|
||||
this.responseBuilder.setResponseStatus(HttpResponseStatus.GONE);
|
||||
}
|
||||
|
||||
private static String toOrigin(URL url) {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
if (url.getPath() != null) {
|
||||
sb.append(url.getPath());
|
||||
}
|
||||
if (url.getQuery() != null) {
|
||||
sb.append('?').append(url.getQuery());
|
||||
}
|
||||
if (url.getFragment() != null) {
|
||||
sb.append('#').append(url.getFragment());
|
||||
}
|
||||
if (sb.length() == 0) {
|
||||
sb.append('/');
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -25,10 +25,11 @@ dependencyResolutionManagement {
|
|||
library('jackson', 'com.fasterxml.jackson.core', 'jackson-databind').version('2.14.2')
|
||||
library('jna', 'net.java.dev.jna', 'jna').version('5.13.0')
|
||||
library('groovy-templates', 'org.apache.groovy', 'groovy-templates').versionRef('groovy')
|
||||
library('j2html', 'com.j2html', 'j2html').version('1.6.0')
|
||||
library('htmlflow', 'com.github.xmlet', 'htmlflow').version('4.0')
|
||||
library('webjars-bootstrap', 'org.webjars', 'bootstrap').version('5.2.3')
|
||||
library('webjars-jquery', 'org.webjars', 'jquery').version('3.6.4')
|
||||
library('webjars-fontawesome', 'org.webjars', 'font-awesome').version('6.3.0')
|
||||
library('j2html', 'com.j2html', 'j2html').version('1.6.0')
|
||||
library('net', 'org.xbib', 'net').versionRef('net')
|
||||
library('net-mime', 'org.xbib', 'net-mime').versionRef('net')
|
||||
library('net-security', 'org.xbib', 'net-security').versionRef('net')
|
||||
|
@ -62,6 +63,7 @@ include 'net-http-server-nio'
|
|||
include 'net-http-server-simple'
|
||||
include 'net-http-server-simple-secure'
|
||||
include 'net-http-template-groovy'
|
||||
include 'net-http-htmlflow'
|
||||
include 'net-http-j2html'
|
||||
include 'net-http-server-application-web'
|
||||
include 'net-http-server-application-config'
|
||||
|
|
Loading…
Reference in a new issue