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() {
|
||||
logger.log(Level.FINER, "closing channel " + ctx.channel());
|
||||
ctx.close();
|
||||
}
|
||||
|
||||
|
@ -218,9 +219,11 @@ public class HttpResponseBuilder extends BaseHttpResponseBuilder {
|
|||
ChannelFuture channelFuture = ctx.writeAndFlush(LastHttpContent.EMPTY_LAST_CONTENT);
|
||||
if (headers.containsHeader(HttpHeaderNames.CONTENT_LENGTH)) {
|
||||
if (!keepAlive) {
|
||||
logger.log(Level.FINER, "adding close listener to channel future " + channelFuture);
|
||||
channelFuture.addListener(CLOSE);
|
||||
}
|
||||
} else {
|
||||
logger.log(Level.FINER, "adding close listener to channel future " + channelFuture);
|
||||
channelFuture.addListener(CLOSE);
|
||||
}
|
||||
});
|
||||
|
@ -231,7 +234,6 @@ public class HttpResponseBuilder extends BaseHttpResponseBuilder {
|
|||
logger.log(Level.WARNING, "channel not writeable: " + ctx.channel());
|
||||
return;
|
||||
}
|
||||
// TODO we write a single chunk, but we should use chunked output here.
|
||||
ByteBuf buffer;
|
||||
int count;
|
||||
try {
|
||||
|
@ -246,7 +248,6 @@ public class HttpResponseBuilder extends BaseHttpResponseBuilder {
|
|||
return;
|
||||
}
|
||||
if (count < bufferSize) {
|
||||
// not chunked, no headers (???)
|
||||
internalBufferWrite(buffer, count);
|
||||
} else {
|
||||
// chunked
|
||||
|
@ -269,14 +270,15 @@ public class HttpResponseBuilder extends BaseHttpResponseBuilder {
|
|||
}
|
||||
defaultHttpResponse.headers().set(headers);
|
||||
ctx.write(defaultHttpResponse);
|
||||
//ctx.write(buffer); ???
|
||||
ctx.write(new ChunkedStream(inputStream, bufferSize));
|
||||
ChannelFuture channelFuture = ctx.writeAndFlush(LastHttpContent.EMPTY_LAST_CONTENT);
|
||||
if (headers.contains(HttpHeaderNames.CONTENT_LENGTH)) {
|
||||
if (!keepAlive) {
|
||||
logger.log(Level.FINER, "adding close listener to channel future " + channelFuture);
|
||||
channelFuture.addListener(CLOSE);
|
||||
}
|
||||
} else {
|
||||
logger.log(Level.FINER, "adding close listener to channel future " + channelFuture);
|
||||
channelFuture.addListener(CLOSE);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -80,7 +80,7 @@ public abstract class BaseHttpResponseBuilder implements HttpResponseBuilder {
|
|||
|
||||
public void reset() {
|
||||
this.version = HttpVersion.HTTP_1_1;
|
||||
this.status = HttpResponseStatus.OK;
|
||||
this.status = null; // must be undefined here
|
||||
this.headers = new HttpHeaders();
|
||||
this.trailingHeaders = new HttpHeaders();
|
||||
this.contentType = HttpHeaderValues.APPLICATION_OCTET_STREAM;
|
||||
|
@ -107,11 +107,11 @@ public abstract class BaseHttpResponseBuilder implements HttpResponseBuilder {
|
|||
|
||||
@Override
|
||||
public BaseHttpResponseBuilder setResponseStatus(HttpResponseStatus status) {
|
||||
if (this.status != null) {
|
||||
logger.log(Level.WARNING, "status rejected: " + status + " status is already " + this.status);
|
||||
return this;
|
||||
if (this.status == null) {
|
||||
this.status = status;
|
||||
} else {
|
||||
logger.log(Level.WARNING, "ignoring status = " + status + " because already set: " + this.status);
|
||||
}
|
||||
this.status = status;
|
||||
return this;
|
||||
}
|
||||
|
||||
|
@ -129,20 +129,18 @@ public abstract class BaseHttpResponseBuilder implements HttpResponseBuilder {
|
|||
public BaseHttpResponseBuilder setHeader(CharSequence name, String value) {
|
||||
if (HttpHeaderNames.CONTENT_TYPE.equalsIgnoreCase(name.toString())) {
|
||||
setContentType(value);
|
||||
} else {
|
||||
if (!headers.containsHeader(name)) {
|
||||
headers.set(name, value);
|
||||
} else {
|
||||
logger.log(Level.WARNING, "header rejected: " + name + " = " + value);
|
||||
}
|
||||
}
|
||||
if (headers.containsHeader(name)) {
|
||||
logger.log(Level.WARNING, "header already exist: " + headers.get(name) + " overwriting with " + value);
|
||||
}
|
||||
headers.set(name, value);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public BaseHttpResponseBuilder addHeader(CharSequence name, String value) {
|
||||
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);
|
||||
return this;
|
||||
|
@ -288,6 +286,10 @@ public abstract class BaseHttpResponseBuilder implements HttpResponseBuilder {
|
|||
}
|
||||
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 (!headers.containsHeader(HttpHeaderNames.CONTENT_LENGTH)) {
|
||||
headers.add(HttpHeaderNames.CONTENT_LENGTH, Long.toString(contentLength));
|
||||
|
@ -302,11 +304,15 @@ public abstract class BaseHttpResponseBuilder implements HttpResponseBuilder {
|
|||
if (httpServerConfig != null && httpServerConfig.getServerName() != null) {
|
||||
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() {
|
||||
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);
|
||||
for (Pair<String, String> e : headers.entries()) {
|
||||
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 {
|
||||
logger.log(Level.FINE, "handle: before creating resource " + this.getClass().getName());
|
||||
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()) {
|
||||
logger.log(Level.FINER, "resource does not exist: " + resource);
|
||||
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);
|
||||
context.response()
|
||||
.addHeader(HttpHeaderNames.LOCATION, loc)
|
||||
.setResponseStatus(HttpResponseStatus.TEMPORARY_REDIRECT)
|
||||
.setResponseStatus(HttpResponseStatus.TEMPORARY_REDIRECT) // 307
|
||||
.build().flush(); // flush is important
|
||||
} else if (resource.isExistsIndexFile()) {
|
||||
// external redirect to default index file in this directory
|
||||
logger.log(Level.FINER, "external redirect to default index file in this directory: " + resource.getIndexFileName());
|
||||
context.response()
|
||||
.addHeader(HttpHeaderNames.LOCATION, resource.getIndexFileName())
|
||||
.setResponseStatus(HttpResponseStatus.TEMPORARY_REDIRECT)
|
||||
.setResponseStatus(HttpResponseStatus.TEMPORARY_REDIRECT) // 307
|
||||
.build()
|
||||
.flush(); // write headers
|
||||
} else {
|
||||
|
@ -102,14 +102,14 @@ public abstract class AbstractResourceHandler implements HttpHandler {
|
|||
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.getLength() == 0) {
|
||||
logger.log(Level.FINE, "the resource length is 0, do nothing");
|
||||
context.response().build().flush();
|
||||
return;
|
||||
}
|
||||
HttpHeaders headers = context.request().getHeaders();
|
||||
logger.log(Level.FINE, "before generating resource, the response headers are " + context.response().getHeaders());
|
||||
String contentType = resource.getMimeType();
|
||||
context.response()
|
||||
.addHeader(HttpHeaderNames.CONTENT_TYPE, contentType);
|
||||
context.response().addHeader(HttpHeaderNames.CONTENT_TYPE, contentType);
|
||||
// heuristic for inline disposition
|
||||
String disposition = "inline";
|
||||
if (!contentType.startsWith("text") && !contentType.startsWith("image")) {
|
||||
|
|
|
@ -70,13 +70,13 @@ public class ClassLoaderResourceHandler extends AbstractResourceHandler {
|
|||
|
||||
private final long length;
|
||||
|
||||
private final String contentType;
|
||||
private final String mimeType;
|
||||
|
||||
private URL url;
|
||||
|
||||
ClassLoaderResource(HttpServerContext httpServerContext) throws IOException {
|
||||
String effectivePath = httpServerContext.request().getRequestPath().substring(1); // httpServerContext.getEffectiveRequestPath();
|
||||
this.contentType = mimeTypeService.getContentType(effectivePath);
|
||||
String effectivePath = httpServerContext.request().getRequestPath().substring(1);
|
||||
this.mimeType = mimeTypeService.getContentType(effectivePath);
|
||||
this.resourcePath = effectivePath.startsWith("/") ? effectivePath.substring(1) : effectivePath;
|
||||
String path = prefix != null ? (prefix.endsWith("/") ? prefix : prefix + "/") : "/";
|
||||
path = resourcePath.startsWith("/") ? path + resourcePath.substring(1) : path + resourcePath;
|
||||
|
@ -161,7 +161,7 @@ public class ClassLoaderResourceHandler extends AbstractResourceHandler {
|
|||
|
||||
@Override
|
||||
public String getMimeType() {
|
||||
return contentType;
|
||||
return mimeType;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -178,6 +178,7 @@ public class ClassLoaderResourceHandler extends AbstractResourceHandler {
|
|||
public String toString() {
|
||||
return "[ClassLoaderResource:resourcePath=" + resourcePath +
|
||||
",url=" + url +
|
||||
",mimeType=" + mimeType +
|
||||
",lastmodified=" + lastModified +
|
||||
",length=" + length +
|
||||
",isDirectory=" + isDirectory() + "]";
|
||||
|
|
|
@ -46,10 +46,14 @@ public class FileResourceHandler extends AbstractResourceHandler {
|
|||
Resource resource = null;
|
||||
if (pathSpec.endsWith("/")) {
|
||||
if (indexFileName != null) {
|
||||
resource = new FileResource(httpServerContext, pathSpec + indexFileName);
|
||||
resource = new FileResource(httpServerContext, pathSpec + indexFileName);
|
||||
}
|
||||
} else {
|
||||
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;
|
||||
}
|
||||
|
@ -92,7 +96,7 @@ public class FileResourceHandler extends AbstractResourceHandler {
|
|||
|
||||
private final boolean isExistsIndexFile;
|
||||
|
||||
private final String contentType;
|
||||
private final String mimeType;
|
||||
|
||||
private final String name;
|
||||
|
||||
|
@ -107,7 +111,6 @@ public class FileResourceHandler extends AbstractResourceHandler {
|
|||
if (root == null) {
|
||||
throw new IllegalArgumentException("no home path set for template resource resolving");
|
||||
}
|
||||
logger.log(Level.FINE, "root = " + root);
|
||||
if (resourcePath.startsWith("file:")) {
|
||||
this.path = Paths.get(URI.create(resourcePath));
|
||||
this.name = path.getFileName().toString();
|
||||
|
@ -119,7 +122,7 @@ public class FileResourceHandler extends AbstractResourceHandler {
|
|||
this.name = 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.baseName = basename(name);
|
||||
this.suffix = suffix(name);
|
||||
|
@ -136,7 +139,7 @@ public class FileResourceHandler extends AbstractResourceHandler {
|
|||
this.length = Files.size(path);
|
||||
httpServerContext.done();
|
||||
} else {
|
||||
this.lastModified = Instant.now();
|
||||
this.lastModified = Instant.ofEpochMilli(0L);
|
||||
this.length = 0;
|
||||
}
|
||||
}
|
||||
|
@ -183,7 +186,7 @@ public class FileResourceHandler extends AbstractResourceHandler {
|
|||
|
||||
@Override
|
||||
public String getMimeType() {
|
||||
return contentType;
|
||||
return mimeType;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -210,7 +213,9 @@ public class FileResourceHandler extends AbstractResourceHandler {
|
|||
public String toString() {
|
||||
return "[FileResource:resourcePath=" + resourcePath +
|
||||
",url=" + url +
|
||||
",mimeType=" + mimeType +
|
||||
",lastmodified=" + lastModified +
|
||||
",isexists=" + isExists +
|
||||
",length=" + length +
|
||||
",isDirectory=" + isDirectory() + "]";
|
||||
}
|
||||
|
|
|
@ -165,75 +165,48 @@ public abstract class DefaultMarkupTemplate extends BaseTemplate {
|
|||
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() {
|
||||
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() {
|
||||
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() {
|
||||
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() {
|
||||
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() {
|
||||
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;
|
||||
|
||||
import groovy.text.markup.BaseTemplate;
|
||||
import org.xbib.net.http.server.BaseApplicationModule;
|
||||
import org.xbib.net.http.server.Application;
|
||||
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.UncheckedIOException;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import org.xbib.net.http.server.HttpService;
|
||||
import org.xbib.settings.Settings;
|
||||
|
||||
public class GroovyTemplateApplicationModule extends BaseApplicationModule {
|
||||
|
||||
private static final Logger logger = Logger.getLogger(GroovyTemplateApplicationModule.class.getName());
|
||||
|
||||
private GroovyMarkupTemplateHandler groovyMarkupTemplateHandler;
|
||||
|
||||
private GroovyTemplateRenderer groovyTemplateRenderer;
|
||||
|
@ -22,8 +28,29 @@ public class GroovyTemplateApplicationModule extends BaseApplicationModule {
|
|||
|
||||
@Override
|
||||
public void onOpen(Application application, Settings settings) {
|
||||
this.groovyMarkupTemplateHandler = new GroovyMarkupTemplateHandler(application);
|
||||
this.groovyTemplateRenderer = new GroovyTemplateRenderer();
|
||||
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();
|
||||
} catch (Exception e) {
|
||||
throw new IllegalStateException(e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -3,7 +3,7 @@ dependencyResolutionManagement {
|
|||
libs {
|
||||
version('gradle', '7.5.1')
|
||||
version('junit', '5.9.2')
|
||||
version('groovy', '4.0.7')
|
||||
version('groovy', '4.0.8')
|
||||
version('netty', '4.1.89.Final')
|
||||
version('netty-tcnative', '2.0.59.Final')
|
||||
version('datastructures', '2.0.0')
|
||||
|
@ -14,10 +14,6 @@ dependencyResolutionManagement {
|
|||
library('junit-jupiter-engine', 'org.junit.jupiter', 'junit-jupiter-engine').versionRef('junit')
|
||||
library('junit4', 'junit', 'junit').version('4.13.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-handler', 'io.netty', 'netty-handler').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('jna', 'net.java.dev.jna', 'jna').version('5.12.1')
|
||||
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('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-json-tiny', 'org.xbib', 'datastructures-json-tiny').versionRef('datastructures')
|
||||
library('datastructures-yaml-tiny', 'org.xbib', 'datastructures-yaml-tiny').versionRef('datastructures')
|
||||
|
|
Loading…
Reference in a new issue