mirror of
https://code.briarproject.org/briar/briar.git
synced 2026-02-11 18:29:05 +01:00
Migrate REST classes to Kotlin and upgrade Javalin
This commit is contained in:
11
.idea/codeStyles/Project.xml
generated
11
.idea/codeStyles/Project.xml
generated
@@ -36,6 +36,9 @@
|
|||||||
<option name="JD_ALIGN_PARAM_COMMENTS" value="false" />
|
<option name="JD_ALIGN_PARAM_COMMENTS" value="false" />
|
||||||
<option name="JD_ALIGN_EXCEPTION_COMMENTS" value="false" />
|
<option name="JD_ALIGN_EXCEPTION_COMMENTS" value="false" />
|
||||||
</JavaCodeStyleSettings>
|
</JavaCodeStyleSettings>
|
||||||
|
<JetCodeStyleSettings>
|
||||||
|
<option name="CODE_STYLE_DEFAULTS" value="KOTLIN_OFFICIAL" />
|
||||||
|
</JetCodeStyleSettings>
|
||||||
<Objective-C-extensions>
|
<Objective-C-extensions>
|
||||||
<file>
|
<file>
|
||||||
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Import" />
|
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Import" />
|
||||||
@@ -258,14 +261,10 @@
|
|||||||
</arrangement>
|
</arrangement>
|
||||||
</codeStyleSettings>
|
</codeStyleSettings>
|
||||||
<codeStyleSettings language="kotlin">
|
<codeStyleSettings language="kotlin">
|
||||||
<option name="CALL_PARAMETERS_WRAP" value="1" />
|
<option name="CODE_STYLE_DEFAULTS" value="KOTLIN_OFFICIAL" />
|
||||||
<option name="METHOD_PARAMETERS_WRAP" value="1" />
|
|
||||||
<option name="EXTENDS_LIST_WRAP" value="1" />
|
|
||||||
<option name="METHOD_CALL_CHAIN_WRAP" value="1" />
|
|
||||||
<option name="ASSIGNMENT_WRAP" value="1" />
|
|
||||||
<option name="PARAMETER_ANNOTATION_WRAP" value="1" />
|
<option name="PARAMETER_ANNOTATION_WRAP" value="1" />
|
||||||
<option name="VARIABLE_ANNOTATION_WRAP" value="1" />
|
<option name="VARIABLE_ANNOTATION_WRAP" value="1" />
|
||||||
<option name="ENUM_CONSTANTS_WRAP" value="1" />
|
<option name="ENUM_CONSTANTS_WRAP" value="1" />
|
||||||
</codeStyleSettings>
|
</codeStyleSettings>
|
||||||
</code_scheme>
|
</code_scheme>
|
||||||
</component>
|
</component>
|
||||||
@@ -14,11 +14,12 @@ dependencies {
|
|||||||
implementation project(path: ':briar-core', configuration: 'default')
|
implementation project(path: ':briar-core', configuration: 'default')
|
||||||
implementation project(path: ':bramble-java', configuration: 'default')
|
implementation project(path: ':bramble-java', configuration: 'default')
|
||||||
|
|
||||||
implementation 'io.javalin:javalin:1.7.0'
|
implementation 'io.javalin:javalin:2.1.0'
|
||||||
implementation 'org.slf4j:slf4j-simple:1.7.25'
|
implementation 'org.slf4j:slf4j-simple:1.7.25'
|
||||||
implementation 'com.fasterxml.jackson.core:jackson-databind:2.9.6'
|
implementation 'com.fasterxml.jackson.core:jackson-databind:2.9.6'
|
||||||
|
|
||||||
apt 'com.google.dagger:dagger-compiler:2.0.2'
|
apt 'com.google.dagger:dagger-compiler:2.0.2'
|
||||||
|
kapt 'com.google.dagger:dagger-compiler:2.0.2'
|
||||||
|
|
||||||
testImplementation project(path: ':bramble-api', configuration: 'testOutput')
|
testImplementation project(path: ':bramble-api', configuration: 'testOutput')
|
||||||
testImplementation project(path: ':bramble-core', configuration: 'testOutput')
|
testImplementation project(path: ':bramble-core', configuration: 'testOutput')
|
||||||
|
|||||||
@@ -1,23 +0,0 @@
|
|||||||
package org.briarproject.bramble.identity;
|
|
||||||
|
|
||||||
import org.briarproject.bramble.api.identity.Author;
|
|
||||||
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
|
||||||
|
|
||||||
import javax.annotation.concurrent.Immutable;
|
|
||||||
|
|
||||||
@Immutable
|
|
||||||
@NotNullByDefault
|
|
||||||
@SuppressWarnings("WeakerAccess")
|
|
||||||
public class OutputAuthor {
|
|
||||||
|
|
||||||
public final byte[] id;
|
|
||||||
public final String name;
|
|
||||||
public final byte[] publicKey;
|
|
||||||
|
|
||||||
public OutputAuthor(Author author) {
|
|
||||||
this.id = author.getId().getBytes();
|
|
||||||
this.name = author.getName();
|
|
||||||
this.publicKey = author.getPublicKey();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -0,0 +1,14 @@
|
|||||||
|
package org.briarproject.bramble.identity
|
||||||
|
|
||||||
|
import org.briarproject.bramble.api.identity.Author
|
||||||
|
import javax.annotation.concurrent.Immutable
|
||||||
|
|
||||||
|
@Immutable
|
||||||
|
@Suppress("unused")
|
||||||
|
class OutputAuthor(author: Author) {
|
||||||
|
|
||||||
|
val id: ByteArray = author.id.bytes
|
||||||
|
val name: String = author.name
|
||||||
|
val publicKey: ByteArray = author.publicKey
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,12 @@
|
|||||||
|
package org.briarproject.briar.headless
|
||||||
|
|
||||||
|
import org.briarproject.bramble.api.identity.Author
|
||||||
|
import org.briarproject.bramble.identity.OutputAuthor
|
||||||
|
import org.briarproject.briar.api.blog.MessageType
|
||||||
|
|
||||||
|
fun Author.output() = OutputAuthor(this)
|
||||||
|
|
||||||
|
fun Author.Status.output() = name.toLowerCase()
|
||||||
|
|
||||||
|
fun MessageType.output() = name.toLowerCase()
|
||||||
|
|
||||||
@@ -1,79 +0,0 @@
|
|||||||
package org.briarproject.briar.headless;
|
|
||||||
|
|
||||||
import org.briarproject.bramble.api.nullsafety.MethodsNotNullByDefault;
|
|
||||||
import org.briarproject.briar.headless.blogs.BlogController;
|
|
||||||
import org.briarproject.briar.headless.contact.ContactController;
|
|
||||||
import org.briarproject.briar.headless.forums.ForumController;
|
|
||||||
import org.briarproject.briar.headless.messaging.MessagingController;
|
|
||||||
|
|
||||||
import javax.annotation.ParametersAreNonnullByDefault;
|
|
||||||
import javax.annotation.concurrent.Immutable;
|
|
||||||
import javax.inject.Inject;
|
|
||||||
import javax.inject.Singleton;
|
|
||||||
|
|
||||||
import io.javalin.Javalin;
|
|
||||||
|
|
||||||
import static io.javalin.ApiBuilder.get;
|
|
||||||
import static io.javalin.ApiBuilder.path;
|
|
||||||
import static io.javalin.ApiBuilder.post;
|
|
||||||
import static io.javalin.event.EventType.SERVER_START_FAILED;
|
|
||||||
import static io.javalin.event.EventType.SERVER_STOPPED;
|
|
||||||
import static java.lang.Runtime.getRuntime;
|
|
||||||
|
|
||||||
@Immutable
|
|
||||||
@Singleton
|
|
||||||
@MethodsNotNullByDefault
|
|
||||||
@ParametersAreNonnullByDefault
|
|
||||||
public class Router {
|
|
||||||
|
|
||||||
private final BriarService briarService;
|
|
||||||
private final ContactController contactController;
|
|
||||||
private final MessagingController messagingController;
|
|
||||||
private final ForumController forumController;
|
|
||||||
private final BlogController blogController;
|
|
||||||
|
|
||||||
@Inject
|
|
||||||
public Router(BriarService briarService,
|
|
||||||
ContactController contactController,
|
|
||||||
MessagingController messagingController,
|
|
||||||
ForumController forumController,
|
|
||||||
BlogController blogController) {
|
|
||||||
this.briarService = briarService;
|
|
||||||
this.contactController = contactController;
|
|
||||||
this.messagingController = messagingController;
|
|
||||||
this.forumController = forumController;
|
|
||||||
this.blogController = blogController;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void start() {
|
|
||||||
briarService.start();
|
|
||||||
getRuntime().addShutdownHook(new Thread(briarService::stop));
|
|
||||||
|
|
||||||
Javalin app = Javalin.create()
|
|
||||||
.port(7000)
|
|
||||||
.disableStartupBanner()
|
|
||||||
.enableStandardRequestLogging()
|
|
||||||
.enableRouteOverview("/")
|
|
||||||
.enableDynamicGzip()
|
|
||||||
.event(SERVER_START_FAILED, event -> briarService.stop())
|
|
||||||
.event(SERVER_STOPPED, event -> briarService.stop())
|
|
||||||
.start();
|
|
||||||
|
|
||||||
app.routes(() -> {
|
|
||||||
path("/contacts", () -> get(contactController::list));
|
|
||||||
path("/messages/:contactId", () -> {
|
|
||||||
get(messagingController::list);
|
|
||||||
post(messagingController::write);
|
|
||||||
});
|
|
||||||
path("/forums", () -> {
|
|
||||||
get(forumController::list);
|
|
||||||
post(forumController::create);
|
|
||||||
});
|
|
||||||
path("/blogs", () -> path("/posts", () -> {
|
|
||||||
get(blogController::listPosts);
|
|
||||||
post(blogController::createPost);
|
|
||||||
}));
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -0,0 +1,68 @@
|
|||||||
|
package org.briarproject.briar.headless
|
||||||
|
|
||||||
|
import io.javalin.Javalin
|
||||||
|
import io.javalin.JavalinEvent.SERVER_START_FAILED
|
||||||
|
import io.javalin.JavalinEvent.SERVER_STOPPED
|
||||||
|
import io.javalin.apibuilder.ApiBuilder.*
|
||||||
|
import org.briarproject.briar.headless.blogs.BlogController
|
||||||
|
import org.briarproject.briar.headless.contact.ContactController
|
||||||
|
import org.briarproject.briar.headless.forums.ForumController
|
||||||
|
import org.briarproject.briar.headless.messaging.MessagingController
|
||||||
|
import java.lang.Runtime.getRuntime
|
||||||
|
import javax.annotation.concurrent.Immutable
|
||||||
|
import javax.inject.Inject
|
||||||
|
import javax.inject.Singleton
|
||||||
|
import kotlin.system.exitProcess
|
||||||
|
|
||||||
|
@Immutable
|
||||||
|
@Singleton
|
||||||
|
class Router @Inject
|
||||||
|
constructor(
|
||||||
|
private val briarService: BriarService,
|
||||||
|
private val contactController: ContactController,
|
||||||
|
private val messagingController: MessagingController,
|
||||||
|
private val forumController: ForumController,
|
||||||
|
private val blogController: BlogController
|
||||||
|
) {
|
||||||
|
|
||||||
|
fun start() {
|
||||||
|
briarService.start()
|
||||||
|
getRuntime().addShutdownHook(Thread(Runnable { briarService.stop() }))
|
||||||
|
|
||||||
|
val app = Javalin.create()
|
||||||
|
.port(7000)
|
||||||
|
.disableStartupBanner()
|
||||||
|
.enableDebugLogging()
|
||||||
|
.enableCaseSensitiveUrls()
|
||||||
|
.enableRouteOverview("/")
|
||||||
|
.event(SERVER_START_FAILED) { stop() }
|
||||||
|
.event(SERVER_STOPPED) { stop() }
|
||||||
|
.start()
|
||||||
|
|
||||||
|
app.routes {
|
||||||
|
path("/contacts") {
|
||||||
|
get { ctx -> contactController.list(ctx) }
|
||||||
|
}
|
||||||
|
path("/messages/:contactId") {
|
||||||
|
get { ctx -> messagingController.list(ctx) }
|
||||||
|
post { ctx -> messagingController.write(ctx) }
|
||||||
|
}
|
||||||
|
path("/forums") {
|
||||||
|
get { ctx -> forumController.list(ctx) }
|
||||||
|
post { ctx -> forumController.create(ctx) }
|
||||||
|
}
|
||||||
|
path("/blogs") {
|
||||||
|
path("/posts") {
|
||||||
|
get { ctx -> blogController.listPosts(ctx) }
|
||||||
|
post { ctx -> blogController.createPost(ctx) }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun stop() {
|
||||||
|
briarService.stop()
|
||||||
|
exitProcess(1)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -1,81 +0,0 @@
|
|||||||
package org.briarproject.briar.headless.blogs;
|
|
||||||
|
|
||||||
import org.briarproject.bramble.api.FormatException;
|
|
||||||
import org.briarproject.bramble.api.db.DbException;
|
|
||||||
import org.briarproject.bramble.api.identity.IdentityManager;
|
|
||||||
import org.briarproject.bramble.api.identity.LocalAuthor;
|
|
||||||
import org.briarproject.bramble.api.nullsafety.MethodsNotNullByDefault;
|
|
||||||
import org.briarproject.bramble.api.system.Clock;
|
|
||||||
import org.briarproject.briar.api.blog.Blog;
|
|
||||||
import org.briarproject.briar.api.blog.BlogManager;
|
|
||||||
import org.briarproject.briar.api.blog.BlogPost;
|
|
||||||
import org.briarproject.briar.api.blog.BlogPostFactory;
|
|
||||||
import org.briarproject.briar.api.blog.BlogPostHeader;
|
|
||||||
|
|
||||||
import java.security.GeneralSecurityException;
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.Collection;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import javax.annotation.ParametersAreNonnullByDefault;
|
|
||||||
import javax.annotation.concurrent.Immutable;
|
|
||||||
import javax.inject.Inject;
|
|
||||||
import javax.inject.Singleton;
|
|
||||||
|
|
||||||
import io.javalin.Context;
|
|
||||||
|
|
||||||
@Immutable
|
|
||||||
@Singleton
|
|
||||||
@MethodsNotNullByDefault
|
|
||||||
@ParametersAreNonnullByDefault
|
|
||||||
public class BlogController {
|
|
||||||
|
|
||||||
private final BlogManager blogManager;
|
|
||||||
private final BlogPostFactory blogPostFactory;
|
|
||||||
private final IdentityManager identityManager;
|
|
||||||
private final Clock clock;
|
|
||||||
|
|
||||||
@Inject
|
|
||||||
public BlogController(BlogManager blogManager,
|
|
||||||
BlogPostFactory blogPostFactory, IdentityManager identityManager,
|
|
||||||
Clock clock) {
|
|
||||||
this.blogManager = blogManager;
|
|
||||||
this.blogPostFactory = blogPostFactory;
|
|
||||||
this.identityManager = identityManager;
|
|
||||||
this.clock = clock;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Context listPosts(Context ctx) throws DbException {
|
|
||||||
List<OutputBlogPost> posts = new ArrayList<>();
|
|
||||||
for (Blog b : blogManager.getBlogs()) {
|
|
||||||
Collection<BlogPostHeader> headers =
|
|
||||||
blogManager.getPostHeaders(b.getId());
|
|
||||||
for (BlogPostHeader header : headers) {
|
|
||||||
String body = blogManager.getPostBody(header.getId());
|
|
||||||
OutputBlogPost post = new OutputBlogPost(header, body);
|
|
||||||
posts.add(post);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return ctx.json(posts);
|
|
||||||
}
|
|
||||||
|
|
||||||
public Context createPost(Context ctx)
|
|
||||||
throws DbException, GeneralSecurityException, FormatException {
|
|
||||||
String text = ctx.formParam("text");
|
|
||||||
if (text == null || text.length() < 1) {
|
|
||||||
return ctx.status(500).result("Expecting Blog text");
|
|
||||||
} else {
|
|
||||||
LocalAuthor author = identityManager.getLocalAuthor();
|
|
||||||
Blog blog = blogManager.getPersonalBlog(author);
|
|
||||||
long now = clock.currentTimeMillis();
|
|
||||||
BlogPost post = blogPostFactory
|
|
||||||
.createBlogPost(blog.getId(), now, null, author, text);
|
|
||||||
blogManager.addLocalPost(post);
|
|
||||||
BlogPostHeader header = blogManager
|
|
||||||
.getPostHeader(blog.getId(), post.getMessage().getId());
|
|
||||||
OutputBlogPost outputPost = new OutputBlogPost(header, text);
|
|
||||||
return ctx.json(outputPost);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -0,0 +1,47 @@
|
|||||||
|
package org.briarproject.briar.headless.blogs
|
||||||
|
|
||||||
|
import io.javalin.BadRequestResponse
|
||||||
|
import io.javalin.Context
|
||||||
|
import org.briarproject.bramble.api.identity.IdentityManager
|
||||||
|
import org.briarproject.bramble.api.system.Clock
|
||||||
|
import org.briarproject.briar.api.blog.BlogManager
|
||||||
|
import org.briarproject.briar.api.blog.BlogPostFactory
|
||||||
|
import javax.annotation.concurrent.Immutable
|
||||||
|
import javax.inject.Inject
|
||||||
|
import javax.inject.Singleton
|
||||||
|
|
||||||
|
@Immutable
|
||||||
|
@Singleton
|
||||||
|
class BlogController @Inject
|
||||||
|
constructor(
|
||||||
|
private val blogManager: BlogManager,
|
||||||
|
private val blogPostFactory: BlogPostFactory,
|
||||||
|
private val identityManager: IdentityManager,
|
||||||
|
private val clock: Clock
|
||||||
|
) {
|
||||||
|
|
||||||
|
fun listPosts(ctx: Context): Context {
|
||||||
|
val posts = blogManager.blogs.flatMap { blog ->
|
||||||
|
blogManager.getPostHeaders(blog.id).map { header ->
|
||||||
|
val body = blogManager.getPostBody(header.id)
|
||||||
|
header.output(body)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ctx.json(posts)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun createPost(ctx: Context): Context {
|
||||||
|
val text = ctx.formParam("text")
|
||||||
|
if (text == null || text.isEmpty())
|
||||||
|
throw BadRequestResponse("Expecting Blog text")
|
||||||
|
|
||||||
|
val author = identityManager.localAuthor
|
||||||
|
val blog = blogManager.getPersonalBlog(author)
|
||||||
|
val now = clock.currentTimeMillis()
|
||||||
|
val post = blogPostFactory.createBlogPost(blog.id, now, null, author, text)
|
||||||
|
blogManager.addLocalPost(post)
|
||||||
|
val header = blogManager.getPostHeader(blog.id, post.message.id)
|
||||||
|
return ctx.json(header.output(text))
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
package org.briarproject.briar.headless.blogs
|
||||||
|
|
||||||
|
import org.briarproject.briar.api.blog.BlogPostHeader
|
||||||
|
|
||||||
|
internal fun BlogPostHeader.output(body: String) = OutputBlogPost(this, body)
|
||||||
@@ -1,38 +0,0 @@
|
|||||||
package org.briarproject.briar.headless.blogs;
|
|
||||||
|
|
||||||
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
|
||||||
import org.briarproject.bramble.identity.OutputAuthor;
|
|
||||||
import org.briarproject.briar.api.blog.BlogPostHeader;
|
|
||||||
|
|
||||||
import javax.annotation.Nullable;
|
|
||||||
import javax.annotation.concurrent.Immutable;
|
|
||||||
|
|
||||||
@Immutable
|
|
||||||
@NotNullByDefault
|
|
||||||
@SuppressWarnings("WeakerAccess")
|
|
||||||
class OutputBlogPost {
|
|
||||||
|
|
||||||
public final String body;
|
|
||||||
public final OutputAuthor author;
|
|
||||||
public final String authorStatus, type;
|
|
||||||
public final byte[] id;
|
|
||||||
@Nullable
|
|
||||||
public final byte[] parentId;
|
|
||||||
public final boolean read, rssFeed;
|
|
||||||
public final long timestamp, timestampReceived;
|
|
||||||
|
|
||||||
OutputBlogPost(BlogPostHeader header, String body) {
|
|
||||||
this.body = body;
|
|
||||||
this.author = new OutputAuthor(header.getAuthor());
|
|
||||||
this.authorStatus = header.getAuthorStatus().name().toLowerCase();
|
|
||||||
this.type = header.getType().name().toLowerCase();
|
|
||||||
this.id = header.getId().getBytes();
|
|
||||||
this.parentId = header.getParentId() == null ? null :
|
|
||||||
header.getParentId().getBytes();
|
|
||||||
this.read = header.isRead();
|
|
||||||
this.rssFeed = header.isRssFeed();
|
|
||||||
this.timestamp = header.getTimestamp();
|
|
||||||
this.timestampReceived = header.getTimeReceived();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -0,0 +1,22 @@
|
|||||||
|
package org.briarproject.briar.headless.blogs
|
||||||
|
|
||||||
|
import org.briarproject.bramble.identity.OutputAuthor
|
||||||
|
import org.briarproject.briar.api.blog.BlogPostHeader
|
||||||
|
import org.briarproject.briar.headless.output
|
||||||
|
import javax.annotation.concurrent.Immutable
|
||||||
|
|
||||||
|
@Immutable
|
||||||
|
@Suppress("unused")
|
||||||
|
internal class OutputBlogPost(header: BlogPostHeader, val body: String) {
|
||||||
|
|
||||||
|
val author: OutputAuthor = OutputAuthor(header.author)
|
||||||
|
val authorStatus: String = header.authorStatus.output()
|
||||||
|
val type = header.type.output()
|
||||||
|
val id: ByteArray = header.id.bytes
|
||||||
|
val parentId = header.parentId?.bytes
|
||||||
|
val read = header.isRead
|
||||||
|
val rssFeed = header.isRssFeed
|
||||||
|
val timestamp = header.timestamp
|
||||||
|
val timestampReceived = header.timeReceived
|
||||||
|
|
||||||
|
}
|
||||||
@@ -1,39 +0,0 @@
|
|||||||
package org.briarproject.briar.headless.contact;
|
|
||||||
|
|
||||||
import org.briarproject.bramble.api.contact.Contact;
|
|
||||||
import org.briarproject.bramble.api.contact.ContactManager;
|
|
||||||
import org.briarproject.bramble.api.db.DbException;
|
|
||||||
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.Collection;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import javax.annotation.concurrent.Immutable;
|
|
||||||
import javax.inject.Inject;
|
|
||||||
import javax.inject.Singleton;
|
|
||||||
|
|
||||||
import io.javalin.Context;
|
|
||||||
|
|
||||||
@Immutable
|
|
||||||
@Singleton
|
|
||||||
@NotNullByDefault
|
|
||||||
public class ContactController {
|
|
||||||
|
|
||||||
private final ContactManager contactManager;
|
|
||||||
|
|
||||||
@Inject
|
|
||||||
public ContactController(ContactManager contactManager) {
|
|
||||||
this.contactManager = contactManager;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Context list(Context ctx) throws DbException {
|
|
||||||
Collection<Contact> contacts = contactManager.getActiveContacts();
|
|
||||||
List<OutputContact> outputContacts = new ArrayList<>(contacts.size());
|
|
||||||
for (Contact c : contacts) {
|
|
||||||
outputContacts.add(new OutputContact(c));
|
|
||||||
}
|
|
||||||
return ctx.json(outputContacts);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -0,0 +1,21 @@
|
|||||||
|
package org.briarproject.briar.headless.contact
|
||||||
|
|
||||||
|
import io.javalin.Context
|
||||||
|
import org.briarproject.bramble.api.contact.ContactManager
|
||||||
|
import javax.annotation.concurrent.Immutable
|
||||||
|
import javax.inject.Inject
|
||||||
|
import javax.inject.Singleton
|
||||||
|
|
||||||
|
@Immutable
|
||||||
|
@Singleton
|
||||||
|
class ContactController @Inject
|
||||||
|
constructor(private val contactManager: ContactManager) {
|
||||||
|
|
||||||
|
fun list(ctx: Context): Context {
|
||||||
|
val contacts = contactManager.activeContacts.map { contact ->
|
||||||
|
contact.output()
|
||||||
|
}
|
||||||
|
return ctx.json(contacts)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
package org.briarproject.briar.headless.contact
|
||||||
|
|
||||||
|
import org.briarproject.bramble.api.contact.Contact
|
||||||
|
|
||||||
|
internal fun Contact.output() = OutputContact(this)
|
||||||
@@ -1,24 +0,0 @@
|
|||||||
package org.briarproject.briar.headless.contact;
|
|
||||||
|
|
||||||
import org.briarproject.bramble.api.contact.Contact;
|
|
||||||
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
|
||||||
import org.briarproject.bramble.identity.OutputAuthor;
|
|
||||||
|
|
||||||
import javax.annotation.concurrent.Immutable;
|
|
||||||
|
|
||||||
@Immutable
|
|
||||||
@NotNullByDefault
|
|
||||||
@SuppressWarnings("WeakerAccess")
|
|
||||||
public class OutputContact {
|
|
||||||
|
|
||||||
public final int id;
|
|
||||||
public final OutputAuthor author;
|
|
||||||
public final boolean verified;
|
|
||||||
|
|
||||||
public OutputContact(Contact c) {
|
|
||||||
this.id = c.getId().getInt();
|
|
||||||
this.author = new OutputAuthor(c.getAuthor());
|
|
||||||
this.verified = c.isVerified();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -0,0 +1,15 @@
|
|||||||
|
package org.briarproject.briar.headless.contact
|
||||||
|
|
||||||
|
import org.briarproject.bramble.api.contact.Contact
|
||||||
|
import org.briarproject.briar.headless.output
|
||||||
|
import javax.annotation.concurrent.Immutable
|
||||||
|
|
||||||
|
@Immutable
|
||||||
|
@Suppress("unused")
|
||||||
|
internal class OutputContact(c: Contact) {
|
||||||
|
|
||||||
|
val id = c.id.int
|
||||||
|
val author = c.author.output()
|
||||||
|
val verified = c.isVerified
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
package org.briarproject.briar.headless.forums
|
||||||
|
|
||||||
|
import org.briarproject.briar.api.forum.Forum
|
||||||
|
|
||||||
|
internal fun Forum.output() = OutputForum(this)
|
||||||
|
|
||||||
|
internal fun Collection<Forum>.output() = map { it.output() }
|
||||||
@@ -1,47 +0,0 @@
|
|||||||
package org.briarproject.briar.headless.forums;
|
|
||||||
|
|
||||||
import org.briarproject.bramble.api.db.DbException;
|
|
||||||
import org.briarproject.bramble.api.nullsafety.MethodsNotNullByDefault;
|
|
||||||
import org.briarproject.briar.api.forum.Forum;
|
|
||||||
import org.briarproject.briar.api.forum.ForumManager;
|
|
||||||
|
|
||||||
import java.util.Collection;
|
|
||||||
|
|
||||||
import javax.annotation.ParametersAreNonnullByDefault;
|
|
||||||
import javax.annotation.concurrent.Immutable;
|
|
||||||
import javax.inject.Inject;
|
|
||||||
import javax.inject.Singleton;
|
|
||||||
|
|
||||||
import io.javalin.Context;
|
|
||||||
|
|
||||||
import static io.javalin.translator.json.JavalinJsonPlugin.getObjectToJsonMapper;
|
|
||||||
|
|
||||||
@Immutable
|
|
||||||
@Singleton
|
|
||||||
@MethodsNotNullByDefault
|
|
||||||
@ParametersAreNonnullByDefault
|
|
||||||
public class ForumController {
|
|
||||||
|
|
||||||
private final ForumManager forumManager;
|
|
||||||
|
|
||||||
@Inject
|
|
||||||
public ForumController(ForumManager forumManager) {
|
|
||||||
this.forumManager = forumManager;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Context list(Context ctx) throws DbException {
|
|
||||||
Collection<Forum> forums = forumManager.getForums();
|
|
||||||
return ctx.result(getObjectToJsonMapper().map(forums));
|
|
||||||
}
|
|
||||||
|
|
||||||
public Context create(Context ctx) throws DbException {
|
|
||||||
String name = ctx.formParam("name");
|
|
||||||
if (name == null || name.length() < 1) {
|
|
||||||
return ctx.status(500).result("Expecting Forum Name");
|
|
||||||
} else {
|
|
||||||
Forum forum = forumManager.addForum(name);
|
|
||||||
return ctx.result(getObjectToJsonMapper().map(forum));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -0,0 +1,26 @@
|
|||||||
|
package org.briarproject.briar.headless.forums
|
||||||
|
|
||||||
|
import io.javalin.BadRequestResponse
|
||||||
|
import io.javalin.Context
|
||||||
|
import org.briarproject.briar.api.forum.ForumManager
|
||||||
|
import javax.annotation.concurrent.Immutable
|
||||||
|
import javax.inject.Inject
|
||||||
|
import javax.inject.Singleton
|
||||||
|
|
||||||
|
@Immutable
|
||||||
|
@Singleton
|
||||||
|
class ForumController @Inject
|
||||||
|
constructor(private val forumManager: ForumManager) {
|
||||||
|
|
||||||
|
fun list(ctx: Context): Context {
|
||||||
|
return ctx.json(forumManager.forums.output())
|
||||||
|
}
|
||||||
|
|
||||||
|
fun create(ctx: Context): Context {
|
||||||
|
val name = ctx.formParam("name")
|
||||||
|
if (name == null || name.isEmpty())
|
||||||
|
throw BadRequestResponse("Expecting Forum Name")
|
||||||
|
return ctx.json(forumManager.addForum(name).output())
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
package org.briarproject.briar.headless.forums
|
||||||
|
|
||||||
|
import org.briarproject.briar.api.forum.Forum
|
||||||
|
import javax.annotation.concurrent.Immutable
|
||||||
|
|
||||||
|
@Immutable
|
||||||
|
@Suppress("unused")
|
||||||
|
internal class OutputForum(forum: Forum) {
|
||||||
|
|
||||||
|
val name: String = forum.name
|
||||||
|
val id: ByteArray = forum.id.bytes
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
package org.briarproject.briar.headless.messaging
|
||||||
|
|
||||||
|
import org.briarproject.briar.api.messaging.PrivateMessage
|
||||||
|
import org.briarproject.briar.api.messaging.PrivateMessageHeader
|
||||||
|
|
||||||
|
internal fun PrivateMessageHeader.output(body: String) = OutputPrivateMessage(this, body)
|
||||||
|
|
||||||
|
internal fun PrivateMessage.output(body: String) = OutputPrivateMessage(this, body)
|
||||||
@@ -1,97 +0,0 @@
|
|||||||
package org.briarproject.briar.headless.messaging;
|
|
||||||
|
|
||||||
import org.briarproject.bramble.api.FormatException;
|
|
||||||
import org.briarproject.bramble.api.contact.Contact;
|
|
||||||
import org.briarproject.bramble.api.contact.ContactId;
|
|
||||||
import org.briarproject.bramble.api.contact.ContactManager;
|
|
||||||
import org.briarproject.bramble.api.db.DbException;
|
|
||||||
import org.briarproject.bramble.api.db.NoSuchContactException;
|
|
||||||
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
|
||||||
import org.briarproject.bramble.api.sync.Group;
|
|
||||||
import org.briarproject.bramble.api.system.Clock;
|
|
||||||
import org.briarproject.briar.api.messaging.MessagingManager;
|
|
||||||
import org.briarproject.briar.api.messaging.PrivateMessage;
|
|
||||||
import org.briarproject.briar.api.messaging.PrivateMessageFactory;
|
|
||||||
import org.briarproject.briar.api.messaging.PrivateMessageHeader;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.Collection;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import javax.annotation.Nullable;
|
|
||||||
import javax.annotation.concurrent.Immutable;
|
|
||||||
import javax.inject.Inject;
|
|
||||||
import javax.inject.Singleton;
|
|
||||||
|
|
||||||
import io.javalin.Context;
|
|
||||||
|
|
||||||
import static org.briarproject.briar.api.messaging.MessagingConstants.MAX_PRIVATE_MESSAGE_BODY_LENGTH;
|
|
||||||
|
|
||||||
@Immutable
|
|
||||||
@Singleton
|
|
||||||
@NotNullByDefault
|
|
||||||
public class MessagingController {
|
|
||||||
|
|
||||||
private final MessagingManager messagingManager;
|
|
||||||
private final PrivateMessageFactory privateMessageFactory;
|
|
||||||
private final ContactManager contactManager;
|
|
||||||
private final Clock clock;
|
|
||||||
|
|
||||||
@Inject
|
|
||||||
public MessagingController(MessagingManager messagingManager,
|
|
||||||
PrivateMessageFactory privateMessageFactory,
|
|
||||||
ContactManager contactManager,
|
|
||||||
Clock clock) {
|
|
||||||
this.messagingManager = messagingManager;
|
|
||||||
this.privateMessageFactory = privateMessageFactory;
|
|
||||||
this.contactManager = contactManager;
|
|
||||||
this.clock = clock;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Context list(Context ctx) throws DbException {
|
|
||||||
Contact contact = getContact(ctx);
|
|
||||||
if (contact == null) return ctx.status(404);
|
|
||||||
|
|
||||||
Collection<PrivateMessageHeader> headers =
|
|
||||||
messagingManager.getMessageHeaders(contact.getId());
|
|
||||||
List<OutputPrivateMessage> messages = new ArrayList<>(headers.size());
|
|
||||||
for (PrivateMessageHeader header : headers) {
|
|
||||||
String body = messagingManager.getMessageBody(header.getId());
|
|
||||||
messages.add(new OutputPrivateMessage(header, body));
|
|
||||||
}
|
|
||||||
return ctx.json(messages);
|
|
||||||
}
|
|
||||||
|
|
||||||
public Context write(Context ctx) throws DbException, FormatException {
|
|
||||||
Contact contact = getContact(ctx);
|
|
||||||
if (contact == null) return ctx.status(404);
|
|
||||||
|
|
||||||
String message = ctx.formParam("message");
|
|
||||||
if (message == null || message.length() < 1)
|
|
||||||
return ctx.status(500).result("Expecting Message text");
|
|
||||||
if (message.length() > MAX_PRIVATE_MESSAGE_BODY_LENGTH)
|
|
||||||
return ctx.status(500).result("Message text too large");
|
|
||||||
|
|
||||||
Group group = messagingManager.getContactGroup(contact);
|
|
||||||
long now = clock.currentTimeMillis();
|
|
||||||
PrivateMessage m = privateMessageFactory
|
|
||||||
.createPrivateMessage(group.getId(), now, message);
|
|
||||||
|
|
||||||
messagingManager.addLocalMessage(m);
|
|
||||||
return ctx.json(new OutputPrivateMessage(m, message));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Nullable
|
|
||||||
private Contact getContact(Context ctx) throws DbException {
|
|
||||||
String contactString = ctx.param("contactId");
|
|
||||||
if (contactString == null) return null;
|
|
||||||
int contactInt = Integer.parseInt(contactString);
|
|
||||||
ContactId contactId = new ContactId(contactInt);
|
|
||||||
try {
|
|
||||||
return contactManager.getContact(contactId);
|
|
||||||
} catch (NoSuchContactException e) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -0,0 +1,66 @@
|
|||||||
|
package org.briarproject.briar.headless.messaging
|
||||||
|
|
||||||
|
import io.javalin.BadRequestResponse
|
||||||
|
import io.javalin.Context
|
||||||
|
import io.javalin.NotFoundResponse
|
||||||
|
import org.briarproject.bramble.api.contact.Contact
|
||||||
|
import org.briarproject.bramble.api.contact.ContactId
|
||||||
|
import org.briarproject.bramble.api.contact.ContactManager
|
||||||
|
import org.briarproject.bramble.api.db.NoSuchContactException
|
||||||
|
import org.briarproject.bramble.api.system.Clock
|
||||||
|
import org.briarproject.briar.api.messaging.MessagingConstants.MAX_PRIVATE_MESSAGE_BODY_LENGTH
|
||||||
|
import org.briarproject.briar.api.messaging.MessagingManager
|
||||||
|
import org.briarproject.briar.api.messaging.PrivateMessageFactory
|
||||||
|
import javax.annotation.concurrent.Immutable
|
||||||
|
import javax.inject.Inject
|
||||||
|
import javax.inject.Singleton
|
||||||
|
|
||||||
|
@Immutable
|
||||||
|
@Singleton
|
||||||
|
class MessagingController @Inject
|
||||||
|
constructor(
|
||||||
|
private val messagingManager: MessagingManager,
|
||||||
|
private val privateMessageFactory: PrivateMessageFactory,
|
||||||
|
private val contactManager: ContactManager,
|
||||||
|
private val clock: Clock
|
||||||
|
) {
|
||||||
|
|
||||||
|
fun list(ctx: Context): Context {
|
||||||
|
val contact = getContact(ctx)
|
||||||
|
|
||||||
|
val messages = messagingManager.getMessageHeaders(contact.id).map { header ->
|
||||||
|
val body = messagingManager.getMessageBody(header.id)
|
||||||
|
header.output(body)
|
||||||
|
}
|
||||||
|
return ctx.json(messages)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun write(ctx: Context): Context {
|
||||||
|
val contact = getContact(ctx)
|
||||||
|
|
||||||
|
val message = ctx.formParam("message")
|
||||||
|
if (message == null || message.isEmpty())
|
||||||
|
throw BadRequestResponse("Expecting Message text")
|
||||||
|
if (message.length > MAX_PRIVATE_MESSAGE_BODY_LENGTH)
|
||||||
|
throw BadRequestResponse("Message text too large")
|
||||||
|
|
||||||
|
val group = messagingManager.getContactGroup(contact)
|
||||||
|
val now = clock.currentTimeMillis()
|
||||||
|
val m = privateMessageFactory.createPrivateMessage(group.id, now, message)
|
||||||
|
|
||||||
|
messagingManager.addLocalMessage(m)
|
||||||
|
return ctx.json(m.output(message))
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun getContact(ctx: Context): Contact {
|
||||||
|
val contactString = ctx.pathParam("contactId")
|
||||||
|
val contactInt = Integer.parseInt(contactString)
|
||||||
|
val contactId = ContactId(contactInt)
|
||||||
|
return try {
|
||||||
|
contactManager.getContact(contactId)
|
||||||
|
} catch (e: NoSuchContactException) {
|
||||||
|
throw NotFoundResponse()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -1,43 +0,0 @@
|
|||||||
package org.briarproject.briar.headless.messaging;
|
|
||||||
|
|
||||||
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
|
||||||
import org.briarproject.briar.api.messaging.PrivateMessage;
|
|
||||||
import org.briarproject.briar.api.messaging.PrivateMessageHeader;
|
|
||||||
|
|
||||||
import javax.annotation.concurrent.Immutable;
|
|
||||||
|
|
||||||
@Immutable
|
|
||||||
@NotNullByDefault
|
|
||||||
@SuppressWarnings("WeakerAccess")
|
|
||||||
public class OutputPrivateMessage {
|
|
||||||
|
|
||||||
public final String body;
|
|
||||||
public final long timestamp;
|
|
||||||
public final boolean read, seen, sent, local;
|
|
||||||
public final byte[] id, groupId;
|
|
||||||
|
|
||||||
OutputPrivateMessage(PrivateMessageHeader header, String body) {
|
|
||||||
this.body = body;
|
|
||||||
this.timestamp = header.getTimestamp();
|
|
||||||
this.read = header.isRead();
|
|
||||||
this.seen = header.isSeen();
|
|
||||||
this.sent = header.isSent();
|
|
||||||
this.local = header.isLocal();
|
|
||||||
this.id = header.getId().getBytes();
|
|
||||||
this.groupId = header.getGroupId().getBytes();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Only meant for own {@link PrivateMessage}s directly after creation.
|
|
||||||
*/
|
|
||||||
OutputPrivateMessage(PrivateMessage m, String body) {
|
|
||||||
this.body = body;
|
|
||||||
this.timestamp = m.getMessage().getTimestamp();
|
|
||||||
this.read = true;
|
|
||||||
this.seen = true;
|
|
||||||
this.sent = false;
|
|
||||||
this.local = true;
|
|
||||||
this.id = m.getMessage().getId().getBytes();
|
|
||||||
this.groupId = m.getMessage().getGroupId().getBytes();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -0,0 +1,44 @@
|
|||||||
|
package org.briarproject.briar.headless.messaging
|
||||||
|
|
||||||
|
import org.briarproject.briar.api.messaging.PrivateMessage
|
||||||
|
import org.briarproject.briar.api.messaging.PrivateMessageHeader
|
||||||
|
import javax.annotation.concurrent.Immutable
|
||||||
|
|
||||||
|
@Immutable
|
||||||
|
@Suppress("unused", "MemberVisibilityCanBePrivate")
|
||||||
|
internal class OutputPrivateMessage {
|
||||||
|
|
||||||
|
val body: String
|
||||||
|
val timestamp: Long
|
||||||
|
val read: Boolean
|
||||||
|
val seen: Boolean
|
||||||
|
val sent: Boolean
|
||||||
|
val local: Boolean
|
||||||
|
val id: ByteArray
|
||||||
|
val groupId: ByteArray
|
||||||
|
|
||||||
|
internal constructor(header: PrivateMessageHeader, body: String) {
|
||||||
|
this.body = body
|
||||||
|
this.timestamp = header.timestamp
|
||||||
|
this.read = header.isRead
|
||||||
|
this.seen = header.isSeen
|
||||||
|
this.sent = header.isSent
|
||||||
|
this.local = header.isLocal
|
||||||
|
this.id = header.id.bytes
|
||||||
|
this.groupId = header.groupId.bytes
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Only meant for own [PrivateMessage]s directly after creation.
|
||||||
|
*/
|
||||||
|
internal constructor(m: PrivateMessage, body: String) {
|
||||||
|
this.body = body
|
||||||
|
this.timestamp = m.message.timestamp
|
||||||
|
this.read = true
|
||||||
|
this.seen = true
|
||||||
|
this.sent = false
|
||||||
|
this.local = true
|
||||||
|
this.id = m.message.id.bytes
|
||||||
|
this.groupId = m.message.groupId.bytes
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -7,7 +7,7 @@ dependencyVerification {
|
|||||||
'com.google.dagger:dagger-producers:2.0-beta:dagger-producers-2.0-beta.jar:99ec15e8a0507ba569e7655bc1165ee5e5ca5aa914b3c8f7e2c2458f724edd6b',
|
'com.google.dagger:dagger-producers:2.0-beta:dagger-producers-2.0-beta.jar:99ec15e8a0507ba569e7655bc1165ee5e5ca5aa914b3c8f7e2c2458f724edd6b',
|
||||||
'com.google.dagger:dagger:2.0.2:dagger-2.0.2.jar:84c0282ed8be73a29e0475d639da030b55dee72369e58dd35ae7d4fe6243dcf9',
|
'com.google.dagger:dagger:2.0.2:dagger-2.0.2.jar:84c0282ed8be73a29e0475d639da030b55dee72369e58dd35ae7d4fe6243dcf9',
|
||||||
'com.google.guava:guava:18.0:guava-18.0.jar:d664fbfc03d2e5ce9cab2a44fb01f1d0bf9dfebeccc1a473b1f9ea31f79f6f99',
|
'com.google.guava:guava:18.0:guava-18.0.jar:d664fbfc03d2e5ce9cab2a44fb01f1d0bf9dfebeccc1a473b1f9ea31f79f6f99',
|
||||||
'io.javalin:javalin:1.7.0:javalin-1.7.0.jar:d97d2044a7b050a3b6564c9a99a0a94a4c6d8c57818033cf0d8236bc90a8069b',
|
'io.javalin:javalin:2.1.0:javalin-2.1.0.jar:d52264afbecddd1a8926a6d3b6f84ca534afa4d3997176c99e96ca2e0874577a',
|
||||||
'io.mockk:mockk-agent-api:1.8.6:mockk-agent-api-1.8.6.jar:613512c66538e6349e03df641a868f4ee324f13e2e1dbd67a0ed388aa664a444',
|
'io.mockk:mockk-agent-api:1.8.6:mockk-agent-api-1.8.6.jar:613512c66538e6349e03df641a868f4ee324f13e2e1dbd67a0ed388aa664a444',
|
||||||
'io.mockk:mockk-agent-common:1.8.6:mockk-agent-common-1.8.6.jar:cb7cb26fae5bfd3c89090858548990f311b27f673b9efa9d0c94f97c463b2863',
|
'io.mockk:mockk-agent-common:1.8.6:mockk-agent-common-1.8.6.jar:cb7cb26fae5bfd3c89090858548990f311b27f673b9efa9d0c94f97c463b2863',
|
||||||
'io.mockk:mockk-agent-jvm:1.8.6:mockk-agent-jvm-1.8.6.jar:3f30b98d23ada8b5a44d75b43cd58fc03252fcb96939ff31e7ad659818af1e5d',
|
'io.mockk:mockk-agent-jvm:1.8.6:mockk-agent-jvm-1.8.6.jar:3f30b98d23ada8b5a44d75b43cd58fc03252fcb96939ff31e7ad659818af1e5d',
|
||||||
@@ -20,29 +20,28 @@ dependencyVerification {
|
|||||||
'net.bytebuddy:byte-buddy-agent:1.8.8:byte-buddy-agent-1.8.8.jar:dc1a2dcefe72731fa89ae84e32231c74d545ccf8216c79865096e546f20c57e8',
|
'net.bytebuddy:byte-buddy-agent:1.8.8:byte-buddy-agent-1.8.8.jar:dc1a2dcefe72731fa89ae84e32231c74d545ccf8216c79865096e546f20c57e8',
|
||||||
'net.bytebuddy:byte-buddy:1.8.8:byte-buddy-1.8.8.jar:30aed1ae2ee5261b1d2f0e98ec3fcb40755c3f61b378089fb65d56098df1f16b',
|
'net.bytebuddy:byte-buddy:1.8.8:byte-buddy-1.8.8.jar:30aed1ae2ee5261b1d2f0e98ec3fcb40755c3f61b378089fb65d56098df1f16b',
|
||||||
'org.apiguardian:apiguardian-api:1.0.0:apiguardian-api-1.0.0.jar:1f58b77470d8d147a0538d515347dd322f49a83b9e884b8970051160464b65b3',
|
'org.apiguardian:apiguardian-api:1.0.0:apiguardian-api-1.0.0.jar:1f58b77470d8d147a0538d515347dd322f49a83b9e884b8970051160464b65b3',
|
||||||
'org.eclipse.jetty.websocket:websocket-api:9.4.9.v20180320:websocket-api-9.4.9.v20180320.jar:985b737f5c0928d48fc9890b261cbed096625350b9c0e321f44bde8a803c85ec',
|
'org.eclipse.jetty.websocket:websocket-api:9.4.11.v20180605:websocket-api-9.4.11.v20180605.jar:924edcf7fb17f2ff2e541afce7fd692305235e51b5a16f7223d7e8b4de77559d',
|
||||||
'org.eclipse.jetty.websocket:websocket-client:9.4.9.v20180320:websocket-client-9.4.9.v20180320.jar:2f5c6a64987ac27a21862a6349bd2b1d25545cba9aa68084e50ef77af7adcd7d',
|
'org.eclipse.jetty.websocket:websocket-client:9.4.11.v20180605:websocket-client-9.4.11.v20180605.jar:d3c812f80ac18d7031ffe2a324f2f83d8b260a99863be81b81668184ad5f2cca',
|
||||||
'org.eclipse.jetty.websocket:websocket-common:9.4.9.v20180320:websocket-common-9.4.9.v20180320.jar:26fc6bba6ad8e6522b27d5f397429c349264bcea076bd186ad885ef0cd0a73c8',
|
'org.eclipse.jetty.websocket:websocket-common:9.4.11.v20180605:websocket-common-9.4.11.v20180605.jar:f00731b8f9d2f2155bd87a2040cdef991fbcd24ff843ff4ba1ab1829bf62c04c',
|
||||||
'org.eclipse.jetty.websocket:websocket-server:9.4.9.v20180320:websocket-server-9.4.9.v20180320.jar:93ebcfa8e8af9876491d1524b4e8d273be8a7576e18b75ef699bad9564f76de2',
|
'org.eclipse.jetty.websocket:websocket-server:9.4.11.v20180605:websocket-server-9.4.11.v20180605.jar:0cfa90029d46618116f986cc6aea1c4f2e7408f3c97ad3eb2f92f74aff37279b',
|
||||||
'org.eclipse.jetty.websocket:websocket-servlet:9.4.9.v20180320:websocket-servlet-9.4.9.v20180320.jar:cac3f46db4917722b860e194907c36c251d2765ca1ce8323085c47cefafec52b',
|
'org.eclipse.jetty.websocket:websocket-servlet:9.4.11.v20180605:websocket-servlet-9.4.11.v20180605.jar:76f52b482ad174944e07f552cbfaaa2ccf498063e0a3837bb930eee8a06373aa',
|
||||||
'org.eclipse.jetty:jetty-client:9.4.9.v20180320:jetty-client-9.4.9.v20180320.jar:d6d8eca17806261a96137f64ad14c33feed26ba031c92180162961589141072d',
|
'org.eclipse.jetty:jetty-client:9.4.11.v20180605:jetty-client-9.4.11.v20180605.jar:b096ea6ee2607886323791930a470b2e04fb3327459b287ef99647226bd7a09c',
|
||||||
'org.eclipse.jetty:jetty-http:9.4.9.v20180320:jetty-http-9.4.9.v20180320.jar:823e76a9565f8a98c96542745f34560e2a6a9dfa6fbe320614061ad9b17b950b',
|
'org.eclipse.jetty:jetty-http:9.4.11.v20180605:jetty-http-9.4.11.v20180605.jar:963b75730aa92b0dfbe65fe8a2e413edc88aeb53e8686ba6b1617d7caeb14067',
|
||||||
'org.eclipse.jetty:jetty-io:9.4.9.v20180320:jetty-io-9.4.9.v20180320.jar:fffa35ca529d3267ad80d87f83ad4f6796b0981ae21d3ff621151bbe0a8f4155',
|
'org.eclipse.jetty:jetty-io:9.4.11.v20180605:jetty-io-9.4.11.v20180605.jar:75c82d6e542a3518e2517c4084c83d8216ec2d2458f8747b8b5c944355ebd732',
|
||||||
'org.eclipse.jetty:jetty-security:9.4.9.v20180320:jetty-security-9.4.9.v20180320.jar:5cbaeb9837aa331a8ee918724786655c6f60f8cc65ab84e03ff587bc212a2327',
|
'org.eclipse.jetty:jetty-security:9.4.11.v20180605:jetty-security-9.4.11.v20180605.jar:5a12b1c69264466004baff33b14fc1555007c86fb2fece2a420c480aa7f8ef56',
|
||||||
'org.eclipse.jetty:jetty-server:9.4.9.v20180320:jetty-server-9.4.9.v20180320.jar:b45869789b8f8081c1c75c059b4fd262d2fd440fa676c54bc753365fdd1f82d6',
|
'org.eclipse.jetty:jetty-server:9.4.11.v20180605:jetty-server-9.4.11.v20180605.jar:b74af5ac482b05c242ed231e00b7c08a0b6649f76f2e039a0885de0cf1376ef8',
|
||||||
'org.eclipse.jetty:jetty-servlet:9.4.9.v20180320:jetty-servlet-9.4.9.v20180320.jar:a96f8711d4f9d5d4c3fcafa046fb5caefec17eefcbfcd35b6c2e1d5a0549edfc',
|
'org.eclipse.jetty:jetty-servlet:9.4.11.v20180605:jetty-servlet-9.4.11.v20180605.jar:e24f145a6d95c7653ad2fe0c34cf8ce7311effb7eb8ed9399fae63d8af63eaf4',
|
||||||
'org.eclipse.jetty:jetty-util:9.4.9.v20180320:jetty-util-9.4.9.v20180320.jar:86ccb5e178e7001f26a12ec4bf56c522911424a0edf60424f15add8601355fc5',
|
'org.eclipse.jetty:jetty-util:9.4.11.v20180605:jetty-util-9.4.11.v20180605.jar:936e5ed74275c16164cc1eccaeae55900eb00edd9f1b1d3b83d70782dd25f505',
|
||||||
'org.eclipse.jetty:jetty-webapp:9.4.9.v20180320:jetty-webapp-9.4.9.v20180320.jar:7d6c6af12f10a47524e8eabc607226b038100680612ea569f92c030158bd5566',
|
'org.eclipse.jetty:jetty-webapp:9.4.11.v20180605:jetty-webapp-9.4.11.v20180605.jar:858f3f16cecb0891f07a4e8d82554201c513bf058c0f65969b366936155b6a36',
|
||||||
'org.eclipse.jetty:jetty-xml:9.4.9.v20180320:jetty-xml-9.4.9.v20180320.jar:2a0c8e64364cb8d0f483e5e050db6fbd26f0ad9e5098367f8af7928887fa5ece',
|
'org.eclipse.jetty:jetty-xml:9.4.11.v20180605:jetty-xml-9.4.11.v20180605.jar:1780bdaee2b1908e032fbc286bb856d730c4d0c9de39d5e14a1b9c48028c295e',
|
||||||
'org.jetbrains.kotlin:kotlin-compiler-embeddable:1.2.61:kotlin-compiler-embeddable-1.2.61.jar:f8165810c61f440a2de6003ed9857d28a1dfc990bacbecee1436610c8ebe565b',
|
'org.jetbrains.kotlin:kotlin-compiler-embeddable:1.2.61:kotlin-compiler-embeddable-1.2.61.jar:f8165810c61f440a2de6003ed9857d28a1dfc990bacbecee1436610c8ebe565b',
|
||||||
'org.jetbrains.kotlin:kotlin-reflect:1.2.41:kotlin-reflect-1.2.41.jar:1bab75771dfa2bb5949cd383ceaedf6f8d354fa0d677804fc5a39e320bab70d3',
|
'org.jetbrains.kotlin:kotlin-reflect:1.2.41:kotlin-reflect-1.2.41.jar:1bab75771dfa2bb5949cd383ceaedf6f8d354fa0d677804fc5a39e320bab70d3',
|
||||||
'org.jetbrains.kotlin:kotlin-reflect:1.2.61:kotlin-reflect-1.2.61.jar:a4f1ed542390f9bf967fb9aff2c232b90988f7ce138a4b7bcc70b754821a8943',
|
'org.jetbrains.kotlin:kotlin-reflect:1.2.61:kotlin-reflect-1.2.61.jar:a4f1ed542390f9bf967fb9aff2c232b90988f7ce138a4b7bcc70b754821a8943',
|
||||||
'org.jetbrains.kotlin:kotlin-script-runtime:1.2.61:kotlin-script-runtime-1.2.61.jar:793e4c54a8d59cf1f1cda68a7bc6be1ad54c41d771a08d308aa28c2cd304f1b1',
|
'org.jetbrains.kotlin:kotlin-script-runtime:1.2.61:kotlin-script-runtime-1.2.61.jar:793e4c54a8d59cf1f1cda68a7bc6be1ad54c41d771a08d308aa28c2cd304f1b1',
|
||||||
'org.jetbrains.kotlin:kotlin-scripting-compiler-embeddable:1.2.61:kotlin-scripting-compiler-embeddable-1.2.61.jar:99e0ee865f9c7c8ddcc0975185c69392182311067fe2a6faa72e942185631c1c',
|
'org.jetbrains.kotlin:kotlin-scripting-compiler-embeddable:1.2.61:kotlin-scripting-compiler-embeddable-1.2.61.jar:99e0ee865f9c7c8ddcc0975185c69392182311067fe2a6faa72e942185631c1c',
|
||||||
'org.jetbrains.kotlin:kotlin-stdlib-common:1.2.61:kotlin-stdlib-common-1.2.61.jar:54a6fab7dae0cd7528208e95868fe1869b01b613c3018f2e53dbbad2604f6595',
|
'org.jetbrains.kotlin:kotlin-stdlib-common:1.2.61:kotlin-stdlib-common-1.2.61.jar:54a6fab7dae0cd7528208e95868fe1869b01b613c3018f2e53dbbad2604f6595',
|
||||||
'org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.2.41:kotlin-stdlib-jdk7-1.2.41.jar:169ee5879cba8444499243ceea5e6a2cb6ecea5424211cc819f0704501154b35',
|
'org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.2.61:kotlin-stdlib-jdk7-1.2.61.jar:f02ed7a640323b162c798a7834b35c10590880151e104eeb83acd84b364ef030',
|
||||||
'org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.2.41:kotlin-stdlib-jdk8-1.2.41.jar:b306e0e6735841e31e320bf3260c71d60fc35057cfa87895f23251ee260a64a8',
|
'org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.2.61:kotlin-stdlib-jdk8-1.2.61.jar:1fdeec7f74c2bae97a2205bb4aff0c6fe9d133bd619d069a0928156098d1b927',
|
||||||
'org.jetbrains.kotlin:kotlin-stdlib:1.2.41:kotlin-stdlib-1.2.41.jar:f0595b9ed88ddc6fd66bddf68c56c6f2f6c4b17faa51e43e478acad32b05303e',
|
|
||||||
'org.jetbrains.kotlin:kotlin-stdlib:1.2.61:kotlin-stdlib-1.2.61.jar:62eaf9cc6e746cef4593abe7cdb4dd48694ef5f817c852e0d9fbbd11fcfc564e',
|
'org.jetbrains.kotlin:kotlin-stdlib:1.2.61:kotlin-stdlib-1.2.61.jar:62eaf9cc6e746cef4593abe7cdb4dd48694ef5f817c852e0d9fbbd11fcfc564e',
|
||||||
'org.jetbrains:annotations:13.0:annotations-13.0.jar:ace2a10dc8e2d5fd34925ecac03e4988b2c0f851650c94b8cef49ba1bd111478',
|
'org.jetbrains:annotations:13.0:annotations-13.0.jar:ace2a10dc8e2d5fd34925ecac03e4988b2c0f851650c94b8cef49ba1bd111478',
|
||||||
'org.junit.jupiter:junit-jupiter-api:5.2.0:junit-jupiter-api-5.2.0.jar:47f7d71b35dc331210b9ab219bbb00d54332981aa12eb5effe817de17e1ae7b3',
|
'org.junit.jupiter:junit-jupiter-api:5.2.0:junit-jupiter-api-5.2.0.jar:47f7d71b35dc331210b9ab219bbb00d54332981aa12eb5effe817de17e1ae7b3',
|
||||||
|
|||||||
Reference in New Issue
Block a user