new bootstrap, allow custom Groovy Default Markup Template class
This commit is contained in:
parent
760e83c035
commit
21f8a03cd5
8 changed files with 111 additions and 97 deletions
|
@ -129,6 +129,7 @@ public class HttpResponseBuilder extends BaseHttpResponseBuilder {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void close() {
|
public void close() {
|
||||||
|
logger.log(Level.FINER, "closing channel " + ctx.channel());
|
||||||
ctx.close();
|
ctx.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -218,9 +219,11 @@ public class HttpResponseBuilder extends BaseHttpResponseBuilder {
|
||||||
ChannelFuture channelFuture = ctx.writeAndFlush(LastHttpContent.EMPTY_LAST_CONTENT);
|
ChannelFuture channelFuture = ctx.writeAndFlush(LastHttpContent.EMPTY_LAST_CONTENT);
|
||||||
if (headers.containsHeader(HttpHeaderNames.CONTENT_LENGTH)) {
|
if (headers.containsHeader(HttpHeaderNames.CONTENT_LENGTH)) {
|
||||||
if (!keepAlive) {
|
if (!keepAlive) {
|
||||||
|
logger.log(Level.FINER, "adding close listener to channel future " + channelFuture);
|
||||||
channelFuture.addListener(CLOSE);
|
channelFuture.addListener(CLOSE);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
logger.log(Level.FINER, "adding close listener to channel future " + channelFuture);
|
||||||
channelFuture.addListener(CLOSE);
|
channelFuture.addListener(CLOSE);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -231,7 +234,6 @@ public class HttpResponseBuilder extends BaseHttpResponseBuilder {
|
||||||
logger.log(Level.WARNING, "channel not writeable: " + ctx.channel());
|
logger.log(Level.WARNING, "channel not writeable: " + ctx.channel());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// TODO we write a single chunk, but we should use chunked output here.
|
|
||||||
ByteBuf buffer;
|
ByteBuf buffer;
|
||||||
int count;
|
int count;
|
||||||
try {
|
try {
|
||||||
|
@ -246,7 +248,6 @@ public class HttpResponseBuilder extends BaseHttpResponseBuilder {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (count < bufferSize) {
|
if (count < bufferSize) {
|
||||||
// not chunked, no headers (???)
|
|
||||||
internalBufferWrite(buffer, count);
|
internalBufferWrite(buffer, count);
|
||||||
} else {
|
} else {
|
||||||
// chunked
|
// chunked
|
||||||
|
@ -269,14 +270,15 @@ public class HttpResponseBuilder extends BaseHttpResponseBuilder {
|
||||||
}
|
}
|
||||||
defaultHttpResponse.headers().set(headers);
|
defaultHttpResponse.headers().set(headers);
|
||||||
ctx.write(defaultHttpResponse);
|
ctx.write(defaultHttpResponse);
|
||||||
//ctx.write(buffer); ???
|
|
||||||
ctx.write(new ChunkedStream(inputStream, bufferSize));
|
ctx.write(new ChunkedStream(inputStream, bufferSize));
|
||||||
ChannelFuture channelFuture = ctx.writeAndFlush(LastHttpContent.EMPTY_LAST_CONTENT);
|
ChannelFuture channelFuture = ctx.writeAndFlush(LastHttpContent.EMPTY_LAST_CONTENT);
|
||||||
if (headers.contains(HttpHeaderNames.CONTENT_LENGTH)) {
|
if (headers.contains(HttpHeaderNames.CONTENT_LENGTH)) {
|
||||||
if (!keepAlive) {
|
if (!keepAlive) {
|
||||||
|
logger.log(Level.FINER, "adding close listener to channel future " + channelFuture);
|
||||||
channelFuture.addListener(CLOSE);
|
channelFuture.addListener(CLOSE);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
logger.log(Level.FINER, "adding close listener to channel future " + channelFuture);
|
||||||
channelFuture.addListener(CLOSE);
|
channelFuture.addListener(CLOSE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -80,7 +80,7 @@ public abstract class BaseHttpResponseBuilder implements HttpResponseBuilder {
|
||||||
|
|
||||||
public void reset() {
|
public void reset() {
|
||||||
this.version = HttpVersion.HTTP_1_1;
|
this.version = HttpVersion.HTTP_1_1;
|
||||||
this.status = HttpResponseStatus.OK;
|
this.status = null; // must be undefined here
|
||||||
this.headers = new HttpHeaders();
|
this.headers = new HttpHeaders();
|
||||||
this.trailingHeaders = new HttpHeaders();
|
this.trailingHeaders = new HttpHeaders();
|
||||||
this.contentType = HttpHeaderValues.APPLICATION_OCTET_STREAM;
|
this.contentType = HttpHeaderValues.APPLICATION_OCTET_STREAM;
|
||||||
|
@ -107,11 +107,11 @@ public abstract class BaseHttpResponseBuilder implements HttpResponseBuilder {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public BaseHttpResponseBuilder setResponseStatus(HttpResponseStatus status) {
|
public BaseHttpResponseBuilder setResponseStatus(HttpResponseStatus status) {
|
||||||
if (this.status != null) {
|
if (this.status == null) {
|
||||||
logger.log(Level.WARNING, "status rejected: " + status + " status is already " + this.status);
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
this.status = status;
|
this.status = status;
|
||||||
|
} else {
|
||||||
|
logger.log(Level.WARNING, "ignoring status = " + status + " because already set: " + this.status);
|
||||||
|
}
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -129,20 +129,18 @@ public abstract class BaseHttpResponseBuilder implements HttpResponseBuilder {
|
||||||
public BaseHttpResponseBuilder setHeader(CharSequence name, String value) {
|
public BaseHttpResponseBuilder setHeader(CharSequence name, String value) {
|
||||||
if (HttpHeaderNames.CONTENT_TYPE.equalsIgnoreCase(name.toString())) {
|
if (HttpHeaderNames.CONTENT_TYPE.equalsIgnoreCase(name.toString())) {
|
||||||
setContentType(value);
|
setContentType(value);
|
||||||
} else {
|
}
|
||||||
if (!headers.containsHeader(name)) {
|
if (headers.containsHeader(name)) {
|
||||||
|
logger.log(Level.WARNING, "header already exist: " + headers.get(name) + " overwriting with " + value);
|
||||||
|
}
|
||||||
headers.set(name, value);
|
headers.set(name, value);
|
||||||
} else {
|
|
||||||
logger.log(Level.WARNING, "header rejected: " + name + " = " + value);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public BaseHttpResponseBuilder addHeader(CharSequence name, String value) {
|
public BaseHttpResponseBuilder addHeader(CharSequence name, String value) {
|
||||||
if (headers.containsHeader(name)) {
|
if (headers.containsHeader(name)) {
|
||||||
logger.log(Level.WARNING, "duplicate header: " + name + " old value = " + headers.get(name) + " new value = " + value);
|
logger.log(Level.WARNING, "header already exist: " + headers.get(name) + " adding " + value);
|
||||||
}
|
}
|
||||||
headers.add(name, value);
|
headers.add(name, value);
|
||||||
return this;
|
return this;
|
||||||
|
@ -288,6 +286,10 @@ public abstract class BaseHttpResponseBuilder implements HttpResponseBuilder {
|
||||||
}
|
}
|
||||||
headers.add(HttpHeaderNames.CONTENT_TYPE, contentType);
|
headers.add(HttpHeaderNames.CONTENT_TYPE, contentType);
|
||||||
}
|
}
|
||||||
|
if (status == null) {
|
||||||
|
logger.log(Level.WARNING, "no status code set by handlers, assuming OK");
|
||||||
|
status = HttpResponseStatus.OK;
|
||||||
|
}
|
||||||
if (status.code() >= 200 && status.code() != 204) {
|
if (status.code() >= 200 && status.code() != 204) {
|
||||||
if (!headers.containsHeader(HttpHeaderNames.CONTENT_LENGTH)) {
|
if (!headers.containsHeader(HttpHeaderNames.CONTENT_LENGTH)) {
|
||||||
headers.add(HttpHeaderNames.CONTENT_LENGTH, Long.toString(contentLength));
|
headers.add(HttpHeaderNames.CONTENT_LENGTH, Long.toString(contentLength));
|
||||||
|
@ -302,11 +304,15 @@ public abstract class BaseHttpResponseBuilder implements HttpResponseBuilder {
|
||||||
if (httpServerConfig != null && httpServerConfig.getServerName() != null) {
|
if (httpServerConfig != null && httpServerConfig.getServerName() != null) {
|
||||||
headers.add(HttpHeaderNames.SERVER, httpServerConfig.getServerName());
|
headers.add(HttpHeaderNames.SERVER, httpServerConfig.getServerName());
|
||||||
}
|
}
|
||||||
logger.log(Level.FINER, "headers built: " + headers);
|
logger.log(Level.FINER, "done: status = " + status + " headers = " + headers);
|
||||||
}
|
}
|
||||||
|
|
||||||
public CharBuffer wrapHeaders() {
|
public CharBuffer wrapHeaders() {
|
||||||
StringBuilder sb = new StringBuilder();
|
StringBuilder sb = new StringBuilder();
|
||||||
|
if (status == null) {
|
||||||
|
logger.log(Level.WARNING, "no status code set by handlers, assuming OK");
|
||||||
|
setResponseStatus(HttpResponseStatus.OK);
|
||||||
|
}
|
||||||
sb.append(version.text()).append(SPACE).append(status.code()).append(SPACE).append(status.reasonPhrase()).append(CRLF);
|
sb.append(version.text()).append(SPACE).append(status.code()).append(SPACE).append(status.reasonPhrase()).append(CRLF);
|
||||||
for (Pair<String, String> e : headers.entries()) {
|
for (Pair<String, String> e : headers.entries()) {
|
||||||
sb.append(e.getKey().toLowerCase(Locale.ROOT)).append(COLON).append(SPACE).append(e.getValue()).append(CRLF);
|
sb.append(e.getKey().toLowerCase(Locale.ROOT)).append(COLON).append(SPACE).append(e.getValue()).append(CRLF);
|
||||||
|
|
|
@ -57,7 +57,7 @@ public abstract class AbstractResourceHandler implements HttpHandler {
|
||||||
public void handle(HttpServerContext context) throws IOException {
|
public void handle(HttpServerContext context) throws IOException {
|
||||||
logger.log(Level.FINE, "handle: before creating resource " + this.getClass().getName());
|
logger.log(Level.FINE, "handle: before creating resource " + this.getClass().getName());
|
||||||
Resource resource = createResource(context);
|
Resource resource = createResource(context);
|
||||||
logger.log(Level.FINE, "handle: resource = " + (resource != null ? resource.getClass().getName() : null));
|
logger.log(Level.FINE, "handle: resource = " + (resource != null ? resource.getClass().getName() + " " + resource : null));
|
||||||
if (resource == null || !resource.isExists()) {
|
if (resource == null || !resource.isExists()) {
|
||||||
logger.log(Level.FINER, "resource does not exist: " + resource);
|
logger.log(Level.FINER, "resource does not exist: " + resource);
|
||||||
throw new HttpException("resource not found", context, HttpResponseStatus.NOT_FOUND);
|
throw new HttpException("resource not found", context, HttpResponseStatus.NOT_FOUND);
|
||||||
|
@ -74,14 +74,14 @@ public abstract class AbstractResourceHandler implements HttpHandler {
|
||||||
logger.log(Level.FINER, "client must add a /, external redirect to = " + loc);
|
logger.log(Level.FINER, "client must add a /, external redirect to = " + loc);
|
||||||
context.response()
|
context.response()
|
||||||
.addHeader(HttpHeaderNames.LOCATION, loc)
|
.addHeader(HttpHeaderNames.LOCATION, loc)
|
||||||
.setResponseStatus(HttpResponseStatus.TEMPORARY_REDIRECT)
|
.setResponseStatus(HttpResponseStatus.TEMPORARY_REDIRECT) // 307
|
||||||
.build().flush(); // flush is important
|
.build().flush(); // flush is important
|
||||||
} else if (resource.isExistsIndexFile()) {
|
} else if (resource.isExistsIndexFile()) {
|
||||||
// external redirect to default index file in this directory
|
// external redirect to default index file in this directory
|
||||||
logger.log(Level.FINER, "external redirect to default index file in this directory: " + resource.getIndexFileName());
|
logger.log(Level.FINER, "external redirect to default index file in this directory: " + resource.getIndexFileName());
|
||||||
context.response()
|
context.response()
|
||||||
.addHeader(HttpHeaderNames.LOCATION, resource.getIndexFileName())
|
.addHeader(HttpHeaderNames.LOCATION, resource.getIndexFileName())
|
||||||
.setResponseStatus(HttpResponseStatus.TEMPORARY_REDIRECT)
|
.setResponseStatus(HttpResponseStatus.TEMPORARY_REDIRECT) // 307
|
||||||
.build()
|
.build()
|
||||||
.flush(); // write headers
|
.flush(); // write headers
|
||||||
} else {
|
} else {
|
||||||
|
@ -102,14 +102,14 @@ public abstract class AbstractResourceHandler implements HttpHandler {
|
||||||
private void generateCacheableResource(HttpServerContext context, Resource resource) throws IOException {
|
private void generateCacheableResource(HttpServerContext context, Resource resource) throws IOException {
|
||||||
// if resource is length of 0, there is nothing to send. Do not send any content,
|
// if resource is length of 0, there is nothing to send. Do not send any content,
|
||||||
if (resource.getLength() == 0) {
|
if (resource.getLength() == 0) {
|
||||||
|
logger.log(Level.FINE, "the resource length is 0, do nothing");
|
||||||
context.response().build().flush();
|
context.response().build().flush();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
HttpHeaders headers = context.request().getHeaders();
|
HttpHeaders headers = context.request().getHeaders();
|
||||||
logger.log(Level.FINE, "before generating resource, the response headers are " + context.response().getHeaders());
|
logger.log(Level.FINE, "before generating resource, the response headers are " + context.response().getHeaders());
|
||||||
String contentType = resource.getMimeType();
|
String contentType = resource.getMimeType();
|
||||||
context.response()
|
context.response().addHeader(HttpHeaderNames.CONTENT_TYPE, contentType);
|
||||||
.addHeader(HttpHeaderNames.CONTENT_TYPE, contentType);
|
|
||||||
// heuristic for inline disposition
|
// heuristic for inline disposition
|
||||||
String disposition = "inline";
|
String disposition = "inline";
|
||||||
if (!contentType.startsWith("text") && !contentType.startsWith("image")) {
|
if (!contentType.startsWith("text") && !contentType.startsWith("image")) {
|
||||||
|
|
|
@ -70,13 +70,13 @@ public class ClassLoaderResourceHandler extends AbstractResourceHandler {
|
||||||
|
|
||||||
private final long length;
|
private final long length;
|
||||||
|
|
||||||
private final String contentType;
|
private final String mimeType;
|
||||||
|
|
||||||
private URL url;
|
private URL url;
|
||||||
|
|
||||||
ClassLoaderResource(HttpServerContext httpServerContext) throws IOException {
|
ClassLoaderResource(HttpServerContext httpServerContext) throws IOException {
|
||||||
String effectivePath = httpServerContext.request().getRequestPath().substring(1); // httpServerContext.getEffectiveRequestPath();
|
String effectivePath = httpServerContext.request().getRequestPath().substring(1);
|
||||||
this.contentType = mimeTypeService.getContentType(effectivePath);
|
this.mimeType = mimeTypeService.getContentType(effectivePath);
|
||||||
this.resourcePath = effectivePath.startsWith("/") ? effectivePath.substring(1) : effectivePath;
|
this.resourcePath = effectivePath.startsWith("/") ? effectivePath.substring(1) : effectivePath;
|
||||||
String path = prefix != null ? (prefix.endsWith("/") ? prefix : prefix + "/") : "/";
|
String path = prefix != null ? (prefix.endsWith("/") ? prefix : prefix + "/") : "/";
|
||||||
path = resourcePath.startsWith("/") ? path + resourcePath.substring(1) : path + resourcePath;
|
path = resourcePath.startsWith("/") ? path + resourcePath.substring(1) : path + resourcePath;
|
||||||
|
@ -161,7 +161,7 @@ public class ClassLoaderResourceHandler extends AbstractResourceHandler {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getMimeType() {
|
public String getMimeType() {
|
||||||
return contentType;
|
return mimeType;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -178,6 +178,7 @@ public class ClassLoaderResourceHandler extends AbstractResourceHandler {
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return "[ClassLoaderResource:resourcePath=" + resourcePath +
|
return "[ClassLoaderResource:resourcePath=" + resourcePath +
|
||||||
",url=" + url +
|
",url=" + url +
|
||||||
|
",mimeType=" + mimeType +
|
||||||
",lastmodified=" + lastModified +
|
",lastmodified=" + lastModified +
|
||||||
",length=" + length +
|
",length=" + length +
|
||||||
",isDirectory=" + isDirectory() + "]";
|
",isDirectory=" + isDirectory() + "]";
|
||||||
|
|
|
@ -50,6 +50,10 @@ public class FileResourceHandler extends AbstractResourceHandler {
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
resource = new FileResource(httpServerContext, pathSpec);
|
resource = new FileResource(httpServerContext, pathSpec);
|
||||||
|
if (resource.isDirectory() && resource.isExistsIndexFile()) {
|
||||||
|
logger.log(Level.FINER, "we have a directory and existing index file, so we redirect internally");
|
||||||
|
resource = new FileResource(httpServerContext, pathSpec + indexFileName);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return resource;
|
return resource;
|
||||||
}
|
}
|
||||||
|
@ -92,7 +96,7 @@ public class FileResourceHandler extends AbstractResourceHandler {
|
||||||
|
|
||||||
private final boolean isExistsIndexFile;
|
private final boolean isExistsIndexFile;
|
||||||
|
|
||||||
private final String contentType;
|
private final String mimeType;
|
||||||
|
|
||||||
private final String name;
|
private final String name;
|
||||||
|
|
||||||
|
@ -107,7 +111,6 @@ public class FileResourceHandler extends AbstractResourceHandler {
|
||||||
if (root == null) {
|
if (root == null) {
|
||||||
throw new IllegalArgumentException("no home path set for template resource resolving");
|
throw new IllegalArgumentException("no home path set for template resource resolving");
|
||||||
}
|
}
|
||||||
logger.log(Level.FINE, "root = " + root);
|
|
||||||
if (resourcePath.startsWith("file:")) {
|
if (resourcePath.startsWith("file:")) {
|
||||||
this.path = Paths.get(URI.create(resourcePath));
|
this.path = Paths.get(URI.create(resourcePath));
|
||||||
this.name = path.getFileName().toString();
|
this.name = path.getFileName().toString();
|
||||||
|
@ -119,7 +122,7 @@ public class FileResourceHandler extends AbstractResourceHandler {
|
||||||
this.name = normalizedPath;
|
this.name = normalizedPath;
|
||||||
this.path = httpServerContext.resolve(webRoot).resolve(normalizedPath);
|
this.path = httpServerContext.resolve(webRoot).resolve(normalizedPath);
|
||||||
}
|
}
|
||||||
this.contentType = mimeTypeService.getContentType(resourcePath);
|
this.mimeType = mimeTypeService.getContentType(resourcePath);
|
||||||
this.url = URL.create(path.toUri().toString());
|
this.url = URL.create(path.toUri().toString());
|
||||||
this.baseName = basename(name);
|
this.baseName = basename(name);
|
||||||
this.suffix = suffix(name);
|
this.suffix = suffix(name);
|
||||||
|
@ -136,7 +139,7 @@ public class FileResourceHandler extends AbstractResourceHandler {
|
||||||
this.length = Files.size(path);
|
this.length = Files.size(path);
|
||||||
httpServerContext.done();
|
httpServerContext.done();
|
||||||
} else {
|
} else {
|
||||||
this.lastModified = Instant.now();
|
this.lastModified = Instant.ofEpochMilli(0L);
|
||||||
this.length = 0;
|
this.length = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -183,7 +186,7 @@ public class FileResourceHandler extends AbstractResourceHandler {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getMimeType() {
|
public String getMimeType() {
|
||||||
return contentType;
|
return mimeType;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -210,7 +213,9 @@ public class FileResourceHandler extends AbstractResourceHandler {
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return "[FileResource:resourcePath=" + resourcePath +
|
return "[FileResource:resourcePath=" + resourcePath +
|
||||||
",url=" + url +
|
",url=" + url +
|
||||||
|
",mimeType=" + mimeType +
|
||||||
",lastmodified=" + lastModified +
|
",lastmodified=" + lastModified +
|
||||||
|
",isexists=" + isExists +
|
||||||
",length=" + length +
|
",length=" + length +
|
||||||
",isDirectory=" + isDirectory() + "]";
|
",isDirectory=" + isDirectory() + "]";
|
||||||
}
|
}
|
||||||
|
|
|
@ -165,75 +165,48 @@ public abstract class DefaultMarkupTemplate extends BaseTemplate {
|
||||||
return ZonedDateTime.now().format(formatter);
|
return ZonedDateTime.now().format(formatter);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public String longDateTimeNow() {
|
||||||
|
DateTimeFormatter formatter = DateTimeFormatter
|
||||||
|
.ofLocalizedDateTime(FormatStyle.LONG, FormatStyle.LONG)
|
||||||
|
.withLocale(application.getLocale())
|
||||||
|
.withZone(application.getZoneId());
|
||||||
|
return ZonedDateTime.now().format(formatter);
|
||||||
|
}
|
||||||
|
|
||||||
|
public String mediumDateTimeNow() {
|
||||||
|
DateTimeFormatter formatter = DateTimeFormatter
|
||||||
|
.ofLocalizedDateTime(FormatStyle.MEDIUM, FormatStyle.MEDIUM)
|
||||||
|
.withLocale(application.getLocale())
|
||||||
|
.withZone(application.getZoneId());
|
||||||
|
return ZonedDateTime.now().format(formatter);
|
||||||
|
}
|
||||||
|
|
||||||
|
public String shortDateTimeNow() {
|
||||||
|
DateTimeFormatter formatter = DateTimeFormatter
|
||||||
|
.ofLocalizedDateTime(FormatStyle.SHORT, FormatStyle.SHORT)
|
||||||
|
.withLocale(application.getLocale())
|
||||||
|
.withZone(application.getZoneId());
|
||||||
|
return ZonedDateTime.now().format(formatter);
|
||||||
|
}
|
||||||
|
|
||||||
public String bootstrapCss() {
|
public String bootstrapCss() {
|
||||||
return contextPath("webjars/bootstrap/3.4.1/dist/css/bootstrap.min.css");
|
return contextPath("webjars/bootstrap/5.2.2/dist/css/bootstrap.min.css");
|
||||||
}
|
}
|
||||||
|
|
||||||
public String bootstrapJs() {
|
public String bootstrapJs() {
|
||||||
return contextPath("webjars/bootstrap/3.4.1/dist/js/bootstrap.min.js");
|
return contextPath("webjars/bootstrap/5.2.2/dist/js/bootstrap.min.js");
|
||||||
}
|
}
|
||||||
|
|
||||||
public String jqueryJs() {
|
public String jqueryJs() {
|
||||||
return contextPath("webjars/jquery/3.5.1/dist/jquery.min.js");
|
return contextPath("webjars/jquery/3.6.3/dist/jquery.min.js");
|
||||||
}
|
}
|
||||||
|
|
||||||
public String fontawesomeCss() {
|
public String fontawesomeCss() {
|
||||||
return contextPath("webjars/font-awesome/5.14.0/css/all.min.css");
|
return contextPath("webjars/font-awesome/6.3.0/css/all.min.css");
|
||||||
}
|
}
|
||||||
|
|
||||||
public String fontawesomeJs() {
|
public String fontawesomeJs() {
|
||||||
return contextPath("webjars/font-awesome/5.14.0/js/all.min.js");
|
return contextPath("webjars/font-awesome/6.3.0/js/all.min.js");
|
||||||
}
|
}
|
||||||
|
|
||||||
public String popperJs() {
|
|
||||||
return contextPath("webjars/popper.js/1.14.4/umd/popper.min.js");
|
|
||||||
}
|
|
||||||
|
|
||||||
public String fileinputCss() {
|
|
||||||
return contextPath("webjars/bootstrap-fileinput/4.4.8/css/fileinput.min.css");
|
|
||||||
}
|
|
||||||
|
|
||||||
public String fileinputJs() {
|
|
||||||
return contextPath("webjars/bootstrap-fileinput/4.4.8/js/fileinput.min.js");
|
|
||||||
}
|
|
||||||
|
|
||||||
public String fileinputLocale(String locale) {
|
|
||||||
return contextPath("webjars/bootstrap-fileinput/4.4.8/js/locales/" + locale + ".js");
|
|
||||||
}
|
|
||||||
|
|
||||||
public String fileinputTheme(String theme) {
|
|
||||||
return contextPath("webjars/bootstrap-fileinput/4.4.8/themes/" + theme + "/theme.min.js");
|
|
||||||
}
|
|
||||||
|
|
||||||
public String datatablesCss() {
|
|
||||||
return contextPath("webjars/datatables/1.10.19/css/jquery.dataTables.min.css");
|
|
||||||
}
|
|
||||||
|
|
||||||
public String datatablesJs() {
|
|
||||||
return contextPath("webjars/datatables/1.10.19/js/jquery.dataTables.min.js");
|
|
||||||
}
|
|
||||||
|
|
||||||
public String bootstrapTableCss() {
|
|
||||||
return contextPath("webjars/bootstrap-table/1.15.4/dist/bootstrap-table.min.css");
|
|
||||||
}
|
|
||||||
|
|
||||||
public String bootstrapTableLocale(String locale) {
|
|
||||||
return contextPath("webjars/bootstrap-table/1.15.4/dist/locale/bootstrap-table-${locale}.min.js");
|
|
||||||
}
|
|
||||||
|
|
||||||
public String bootstrapTableJs() {
|
|
||||||
return contextPath("webjars//bootstrap-table/1.15.4/dist/bootstrap-table.min.js");
|
|
||||||
}
|
|
||||||
|
|
||||||
public String bootstrapTableAutoRefreshJs() {
|
|
||||||
return contextPath("webjars/bootstrap-table/1.15.4/dist/extensions/auto-refresh/bootstrap-table-auto-refresh.min.js");
|
|
||||||
}
|
|
||||||
|
|
||||||
public String bootstrapHoverDropdownJs() {
|
|
||||||
return contextPath("webjars/bootstrap-hover-dropdown/2.2.1/bootstrap-hover-dropdown.min.js");
|
|
||||||
}
|
|
||||||
|
|
||||||
public String bootstrapValidatorJs() {
|
|
||||||
return contextPath("webjars/bootstrap-validator/0.11.9/js/validator.js");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
package org.xbib.net.http.template.groovy;
|
package org.xbib.net.http.template.groovy;
|
||||||
|
|
||||||
|
import groovy.text.markup.BaseTemplate;
|
||||||
import org.xbib.net.http.server.BaseApplicationModule;
|
import org.xbib.net.http.server.BaseApplicationModule;
|
||||||
import org.xbib.net.http.server.Application;
|
import org.xbib.net.http.server.Application;
|
||||||
import org.xbib.net.http.server.HttpRequest;
|
import org.xbib.net.http.server.HttpRequest;
|
||||||
|
@ -7,11 +8,16 @@ import org.xbib.net.http.server.HttpServerContext;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.UncheckedIOException;
|
import java.io.UncheckedIOException;
|
||||||
|
import java.util.logging.Level;
|
||||||
|
import java.util.logging.Logger;
|
||||||
|
|
||||||
import org.xbib.net.http.server.HttpService;
|
import org.xbib.net.http.server.HttpService;
|
||||||
import org.xbib.settings.Settings;
|
import org.xbib.settings.Settings;
|
||||||
|
|
||||||
public class GroovyTemplateApplicationModule extends BaseApplicationModule {
|
public class GroovyTemplateApplicationModule extends BaseApplicationModule {
|
||||||
|
|
||||||
|
private static final Logger logger = Logger.getLogger(GroovyTemplateApplicationModule.class.getName());
|
||||||
|
|
||||||
private GroovyMarkupTemplateHandler groovyMarkupTemplateHandler;
|
private GroovyMarkupTemplateHandler groovyMarkupTemplateHandler;
|
||||||
|
|
||||||
private GroovyTemplateRenderer groovyTemplateRenderer;
|
private GroovyTemplateRenderer groovyTemplateRenderer;
|
||||||
|
@ -22,8 +28,29 @@ public class GroovyTemplateApplicationModule extends BaseApplicationModule {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onOpen(Application application, Settings settings) {
|
public void onOpen(Application application, Settings settings) {
|
||||||
this.groovyMarkupTemplateHandler = new GroovyMarkupTemplateHandler(application);
|
ClassLoader classLoader = GroovyMarkupTemplateHandler.class.getClassLoader();
|
||||||
|
String defaultMarkupTemplate = settings.get("markup.templateClass",
|
||||||
|
"org.xbib.net.http.template.DefaultMarkupTemplate");
|
||||||
|
try {
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
Class<? extends BaseTemplate> defaultMarkupTemplateClass =
|
||||||
|
(Class<? extends BaseTemplate>) Class.forName(defaultMarkupTemplate, true, classLoader);
|
||||||
|
logger.log(Level.INFO, "markup template class = " + defaultMarkupTemplateClass.getName());
|
||||||
|
this.groovyMarkupTemplateHandler = new GroovyMarkupTemplateHandler(application,
|
||||||
|
classLoader, defaultMarkupTemplateClass, application.getLocale(),
|
||||||
|
settings.getAsBoolean("markup.autoEscape", true),
|
||||||
|
settings.getAsBoolean("markup.autoIndent", false),
|
||||||
|
settings.get("markup.autoIndentString", " "),
|
||||||
|
settings.getAsBoolean("markup.autoNewline", false),
|
||||||
|
settings.getAsBoolean("markup.cacheTemplates", true),
|
||||||
|
settings.get("markup.declarationEncoding", null),
|
||||||
|
settings.getAsBoolean("markup.expandEmptyElements", true),
|
||||||
|
settings.get("markup.newLine", System.getProperty("line.separator")),
|
||||||
|
settings.getAsBoolean("markup.useDoubleQuotes", true));
|
||||||
this.groovyTemplateRenderer = new GroovyTemplateRenderer();
|
this.groovyTemplateRenderer = new GroovyTemplateRenderer();
|
||||||
|
} catch (Exception e) {
|
||||||
|
throw new IllegalStateException(e);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -3,7 +3,7 @@ dependencyResolutionManagement {
|
||||||
libs {
|
libs {
|
||||||
version('gradle', '7.5.1')
|
version('gradle', '7.5.1')
|
||||||
version('junit', '5.9.2')
|
version('junit', '5.9.2')
|
||||||
version('groovy', '4.0.7')
|
version('groovy', '4.0.8')
|
||||||
version('netty', '4.1.89.Final')
|
version('netty', '4.1.89.Final')
|
||||||
version('netty-tcnative', '2.0.59.Final')
|
version('netty-tcnative', '2.0.59.Final')
|
||||||
version('datastructures', '2.0.0')
|
version('datastructures', '2.0.0')
|
||||||
|
@ -14,10 +14,6 @@ dependencyResolutionManagement {
|
||||||
library('junit-jupiter-engine', 'org.junit.jupiter', 'junit-jupiter-engine').versionRef('junit')
|
library('junit-jupiter-engine', 'org.junit.jupiter', 'junit-jupiter-engine').versionRef('junit')
|
||||||
library('junit4', 'junit', 'junit').version('4.13.2')
|
library('junit4', 'junit', 'junit').version('4.13.2')
|
||||||
library('hamcrest', 'org.hamcrest', 'hamcrest-library').version('2.2')
|
library('hamcrest', 'org.hamcrest', 'hamcrest-library').version('2.2')
|
||||||
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')
|
|
||||||
library('net-bouncycastle', 'org.xbib', 'net-bouncycastle').versionRef('net')
|
|
||||||
library('netty-codec-http2', 'io.netty', 'netty-codec-http2').versionRef('netty')
|
library('netty-codec-http2', 'io.netty', 'netty-codec-http2').versionRef('netty')
|
||||||
library('netty-handler', 'io.netty', 'netty-handler').versionRef('netty')
|
library('netty-handler', 'io.netty', 'netty-handler').versionRef('netty')
|
||||||
library('netty-handler-proxy', 'io.netty', 'netty-handler-proxy').versionRef('netty')
|
library('netty-handler-proxy', 'io.netty', 'netty-handler-proxy').versionRef('netty')
|
||||||
|
@ -29,10 +25,14 @@ dependencyResolutionManagement {
|
||||||
library('jackson', 'com.fasterxml.jackson.core', 'jackson-databind').version('2.12.7')
|
library('jackson', 'com.fasterxml.jackson.core', 'jackson-databind').version('2.12.7')
|
||||||
library('jna', 'net.java.dev.jna', 'jna').version('5.12.1')
|
library('jna', 'net.java.dev.jna', 'jna').version('5.12.1')
|
||||||
library('oracle', 'com.oracle.database.jdbc', 'ojdbc11').version('21.7.0.0')
|
library('oracle', 'com.oracle.database.jdbc', 'ojdbc11').version('21.7.0.0')
|
||||||
library('webjars-bootstrap', 'org.webjars.bower', 'bootstrap').version('3.4.1')
|
|
||||||
library('webjars-jquery', 'org.webjars.bower', 'jquery').version('3.5.1')
|
|
||||||
library('webjars-fontawesome', 'org.webjars', 'font-awesome').version('5.14.0')
|
|
||||||
library('groovy-templates', 'org.apache.groovy', 'groovy-templates').versionRef('groovy')
|
library('groovy-templates', 'org.apache.groovy', 'groovy-templates').versionRef('groovy')
|
||||||
|
library('webjars-bootstrap', 'org.webjars.bower', 'bootstrap').version('5.2.2')
|
||||||
|
library('webjars-jquery', 'org.webjars.bower', 'jquery').version('3.6.3')
|
||||||
|
library('webjars-fontawesome', 'org.webjars', 'font-awesome').version('6.3.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')
|
||||||
|
library('net-bouncycastle', 'org.xbib', 'net-bouncycastle').versionRef('net')
|
||||||
library('datastructures-common', 'org.xbib', 'datastructures-common').versionRef('datastructures')
|
library('datastructures-common', 'org.xbib', 'datastructures-common').versionRef('datastructures')
|
||||||
library('datastructures-json-tiny', 'org.xbib', 'datastructures-json-tiny').versionRef('datastructures')
|
library('datastructures-json-tiny', 'org.xbib', 'datastructures-json-tiny').versionRef('datastructures')
|
||||||
library('datastructures-yaml-tiny', 'org.xbib', 'datastructures-yaml-tiny').versionRef('datastructures')
|
library('datastructures-yaml-tiny', 'org.xbib', 'datastructures-yaml-tiny').versionRef('datastructures')
|
||||||
|
|
Loading…
Reference in a new issue