Verified Commit bda52ea5 authored by akwizgran's avatar akwizgran Committed by Torsten Grote

Use maps for JSON output.

parent cf033dc2
package org.briarproject.bramble.identity
import org.briarproject.bramble.api.identity.Author
import javax.annotation.concurrent.Immutable
@Immutable
data class OutputAuthor(
val id: ByteArray,
val name: String,
val publicKey: ByteArray
) {
constructor(author: Author) : this(
id = author.id.bytes,
name = author.name,
publicKey = author.publicKey
)
}
fun Author.output() = OutputAuthor(this)
fun Author.output() = mapOf(
"formatVersion" to formatVersion,
"id" to id.bytes,
"name" to name,
"publicKey" to publicKey
)
fun Author.Status.output() = name.toLowerCase()
......@@ -23,12 +23,10 @@ internal class BlogControllerImpl
) : BlogController {
override 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)
}
}.sortedBy { it.timestampReceived }
val posts = blogManager.blogs
.flatMap { blog -> blogManager.getPostHeaders(blog.id) }
.sortedBy { it.timeReceived }
.map { header -> header.output(blogManager.getPostBody(header.id)) }
return ctx.json(posts)
}
......
package org.briarproject.briar.headless.blogs
import org.briarproject.bramble.identity.OutputAuthor
import org.briarproject.bramble.identity.output
import org.briarproject.briar.api.blog.BlogPostHeader
import org.briarproject.briar.api.blog.MessageType
import javax.annotation.concurrent.Immutable
@Immutable
internal data class OutputBlogPost(
val body: String,
val author: OutputAuthor,
val authorStatus: String,
val type: String,
val id: ByteArray,
val parentId: ByteArray?,
val read: Boolean,
val rssFeed: Boolean,
val timestamp: Long,
val timestampReceived: Long
) {
internal constructor(header: BlogPostHeader, body: String) : this(
body = body,
author = OutputAuthor(header.author),
authorStatus = header.authorStatus.output(),
type = header.type.output(),
id = header.id.bytes,
parentId = header.parentId?.bytes,
read = header.isRead,
rssFeed = header.isRssFeed,
timestamp = header.timestamp,
timestampReceived = header.timeReceived
)
}
internal fun BlogPostHeader.output(body: String) = OutputBlogPost(this, body)
internal fun BlogPostHeader.output(body: String) = mapOf(
"body" to body,
"author" to author.output(),
"authorStatus" to authorStatus.output(),
"type" to type.output(),
"id" to id.bytes,
"parentId" to parentId?.bytes,
"read" to isRead,
"rssFeed" to isRssFeed,
"timestamp" to timestamp,
"timestampReceived" to timeReceived
)
internal fun MessageType.output() = name.toLowerCase()
package org.briarproject.briar.headless.contact
import org.briarproject.bramble.api.contact.Contact
import org.briarproject.bramble.identity.OutputAuthor
import org.briarproject.bramble.identity.output
import javax.annotation.concurrent.Immutable
@Immutable
internal data class OutputContact(
val contactId: Int,
val author: OutputAuthor,
val verified: Boolean
) {
internal constructor(c: Contact) : this(
contactId = c.id.int,
author = c.author.output(),
verified = c.isVerified
)
}
internal fun Contact.output() = OutputContact(this)
internal fun Contact.output() = mapOf(
"contactId" to id.int,
"author" to author.output(),
"verified" to isVerified
)
\ No newline at end of file
package org.briarproject.briar.headless.forums
import org.briarproject.briar.api.forum.Forum
import javax.annotation.concurrent.Immutable
@Immutable
internal data class OutputForum(
val name: String,
val id: ByteArray
) {
constructor(forum: Forum) : this(
name = forum.name,
id = forum.id.bytes
)
}
internal fun Forum.output() = OutputForum(this)
internal fun Forum.output() = mapOf(
"name" to name,
"id" to id.bytes
)
internal fun Collection<Forum>.output() = map { it.output() }
......@@ -40,16 +40,18 @@ internal class MessagingControllerImpl
override fun list(ctx: Context): Context {
val contact = getContact(ctx)
val messages = conversationManager.getMessageHeaders(contact.id).map { header ->
when (header) {
is PrivateRequest<*> -> header.output(contact.id)
is PrivateResponse -> header.output(contact.id)
else -> {
val body = messagingManager.getMessageBody(header.id)
header.output(contact.id, body)
val messages = conversationManager.getMessageHeaders(contact.id)
.sortedBy { it.timestamp }
.map { header ->
when (header) {
is PrivateRequest<*> -> header.output(contact.id)
is PrivateResponse -> header.output(contact.id)
else -> {
val body = messagingManager.getMessageBody(header.id)
header.output(contact.id, body)
}
}
}
}.sortedBy { it.timestamp }
return ctx.json(messages)
}
......
......@@ -3,56 +3,32 @@ package org.briarproject.briar.headless.messaging
import org.briarproject.bramble.api.contact.ContactId
import org.briarproject.briar.api.messaging.PrivateMessage
import org.briarproject.briar.api.messaging.PrivateMessageHeader
import javax.annotation.concurrent.Immutable
@Immutable
internal abstract class OutputPrivateMessage(
protected open val iHeader: PrivateMessageHeader,
protected open val iContactId: ContactId,
open val body: String?
) {
abstract val type: String
val contactId: Int get() = iContactId.int
val timestamp: Long get() = iHeader.timestamp
val read: Boolean get() = iHeader.isRead
val seen: Boolean get() = iHeader.isSeen
val sent: Boolean get() = iHeader.isSent
val local: Boolean get() = iHeader.isLocal
val id: ByteArray get() = iHeader.id.bytes
val groupId: ByteArray get() = iHeader.groupId.bytes
}
@Immutable
internal data class OutputPrivateMessageHeader(
override val iHeader: PrivateMessageHeader,
override val iContactId: ContactId,
override val body: String?
) : OutputPrivateMessage(iHeader, iContactId, body) {
override val type = "org.briarproject.briar.api.messaging.PrivateMessageHeader"
/**
* Only meant for own [PrivateMessage]s directly after creation.
*/
internal constructor(m: PrivateMessage, contactId: ContactId, body: String) : this(
PrivateMessageHeader(
m.message.id,
m.message.groupId,
m.message.timestamp,
true,
true,
true,
true
), contactId, body
internal fun PrivateMessageHeader.output(contactId: ContactId, body: String?): Map<String, Any> {
val map: HashMap<String, Any> = hashMapOf(
"type" to "org.briarproject.briar.api.messaging.PrivateMessageHeader",
"contactId" to contactId.int,
"timestamp" to timestamp,
"read" to isRead,
"seen" to isSeen,
"sent" to isSent,
"local" to isLocal,
"id" to id.bytes,
"groupId" to groupId.bytes
)
if (body != null) map.put("body", body)
return map
}
internal fun PrivateMessageHeader.output(
contactId: ContactId,
body: String?
) = OutputPrivateMessageHeader(this, contactId, body)
internal fun PrivateMessage.output(contactId: ContactId, body: String) =
OutputPrivateMessageHeader(this, contactId, body)
internal fun PrivateMessage.output(contactId: ContactId, body: String) = mapOf(
"type" to "org.briarproject.briar.api.messaging.PrivateMessageHeader",
"contactId" to contactId.int,
"timestamp" to message.timestamp,
"read" to true,
"seen" to true,
"sent" to true,
"local" to true,
"id" to message.id.bytes,
"groupId" to message.groupId.bytes,
"body" to body
)
\ No newline at end of file
......@@ -6,54 +6,56 @@ import org.briarproject.bramble.api.contact.ContactId
import org.briarproject.briar.api.blog.BlogInvitationRequest
import org.briarproject.briar.api.forum.ForumInvitationRequest
import org.briarproject.briar.api.introduction.IntroductionRequest
import org.briarproject.briar.api.messaging.PrivateMessageHeader
import org.briarproject.briar.api.messaging.PrivateRequest
import org.briarproject.briar.api.privategroup.invitation.GroupInvitationRequest
import org.briarproject.briar.api.sharing.InvitationRequest
import javax.annotation.concurrent.Immutable
@Immutable
internal abstract class OutputPrivateRequest(header: PrivateRequest<*>, contactId: ContactId) :
OutputPrivateMessage(header, contactId, header.message) {
val sessionId: ByteArray = header.sessionId.bytes
val name: String = header.name
val answered = header.wasAnswered()
internal fun PrivateRequest<*>.output(contactId: ContactId): Map<String, Any> {
val map: HashMap<String, Any> = hashMapOf(
"sessionId" to sessionId.bytes,
"name" to name,
"answered" to wasAnswered()
)
map.putAll((this as PrivateMessageHeader).output(contactId, null))
return map
}
@Immutable
internal data class OutputIntroductionRequest(
override val iHeader: IntroductionRequest,
override val iContactId: ContactId
) : OutputPrivateRequest(iHeader, iContactId) {
override val type = "org.briarproject.briar.api.introduction.IntroductionRequest"
val alreadyContact get() = iHeader.isContact
internal fun IntroductionRequest.output(contactId: ContactId): Map<String, Any> {
val map: HashMap<String, Any> = hashMapOf(
"type" to "org.briarproject.briar.api.introduction.IntroductionRequest",
"alreadyContact" to isContact
)
map.putAll((this as PrivateRequest<*>).output(contactId))
return map
}
@Immutable
internal data class OutputInvitationRequest(
override val iHeader: InvitationRequest<*>,
override val iContactId: ContactId
) : OutputPrivateRequest(iHeader, iContactId) {
override val type = when (iHeader) {
is ForumInvitationRequest -> "org.briarproject.briar.api.forum.ForumInvitationRequest"
is BlogInvitationRequest -> "org.briarproject.briar.api.blog.BlogInvitationRequest"
is GroupInvitationRequest -> "org.briarproject.briar.api.privategroup.invitation.GroupInvitationRequest"
else -> throw AssertionError("Unknown InvitationRequest")
}
val canBeOpened get() = iHeader.canBeOpened()
internal fun InvitationRequest<*>.output(contactId : ContactId): Map<String, Any> {
val map: HashMap<String, Any> = hashMapOf("canBeOpened" to canBeOpened())
map.putAll((this as PrivateRequest<*>).output(contactId))
return map
}
internal fun BlogInvitationRequest.output(contactId : ContactId): Map<String, Any> {
val map: HashMap<String, Any> = hashMapOf(
"type" to "org.briarproject.briar.api.blog.BlogInvitationRequest"
)
map.putAll((this as InvitationRequest<*>).output(contactId))
return map
}
internal fun PrivateRequest<*>.output(contactId: ContactId): OutputPrivateMessage {
return when (this) {
is IntroductionRequest -> OutputIntroductionRequest(this, contactId)
is InvitationRequest -> OutputInvitationRequest(this, contactId)
else -> throw AssertionError("Unknown PrivateRequest")
}
internal fun ForumInvitationRequest.output(contactId: ContactId): Map<String, Any> {
val map: HashMap<String, Any> = hashMapOf(
"type" to "org.briarproject.briar.api.forum.ForumInvitationRequest"
)
map.putAll((this as InvitationRequest<*>).output(contactId))
return map
}
internal fun IntroductionRequest.output(contactId: ContactId) =
OutputIntroductionRequest(this, contactId)
internal fun GroupInvitationRequest.output(contactId : ContactId): Map<String, Any> {
val map: HashMap<String, Any> = hashMapOf(
"type" to "org.briarproject.briar.api.privategroup.invitation.GroupInvitationRequest"
)
map.putAll((this as InvitationRequest<*>).output(contactId))
return map
}
\ No newline at end of file
......@@ -7,49 +7,56 @@ import org.briarproject.bramble.identity.output
import org.briarproject.briar.api.blog.BlogInvitationResponse
import org.briarproject.briar.api.forum.ForumInvitationResponse
import org.briarproject.briar.api.introduction.IntroductionResponse
import org.briarproject.briar.api.messaging.PrivateMessageHeader
import org.briarproject.briar.api.messaging.PrivateResponse
import org.briarproject.briar.api.privategroup.invitation.GroupInvitationResponse
import org.briarproject.briar.api.sharing.InvitationResponse
import javax.annotation.concurrent.Immutable
@Immutable
internal abstract class OutputPrivateResponse(header: PrivateResponse, contactId: ContactId) :
OutputPrivateMessage(header, contactId, null) {
val sessionId: ByteArray = header.sessionId.bytes
val accepted = header.wasAccepted()
internal fun PrivateResponse.output(contactId: ContactId): Map<String, Any> {
val map: HashMap<String, Any> = hashMapOf(
"sessionId" to sessionId.bytes,
"accepted" to wasAccepted()
)
map.putAll((this as PrivateMessageHeader).output(contactId, null))
return map
}
@Immutable
internal data class OutputIntroductionResponse(
override val iHeader: IntroductionResponse,
override val iContactId: ContactId
) : OutputPrivateResponse(iHeader, iContactId) {
internal fun IntroductionResponse.output(contactId: ContactId): Map<String, Any> {
val map: HashMap<String, Any> = hashMapOf(
"type" to "org.briarproject.briar.api.introduction.IntroductionResponse",
"introducedAuthor" to introducedAuthor.output(),
"introducer" to isIntroducer
)
map.putAll((this as PrivateResponse).output(contactId))
return map
}
override val type = "org.briarproject.briar.api.introduction.IntroductionResponse"
val introducedAuthor get() = iHeader.introducedAuthor.output()
val introducer get() = iHeader.isIntroducer
internal fun InvitationResponse.output(contactId: ContactId): Map<String, Any> {
val map: HashMap<String, Any> = hashMapOf("shareableId" to shareableId.bytes)
map.putAll((this as PrivateResponse).output(contactId))
return map
}
@Immutable
internal data class OutputInvitationResponse(
override val iHeader: InvitationResponse,
override val iContactId: ContactId
) : OutputPrivateResponse(iHeader, iContactId) {
override val type = when (iHeader) {
is ForumInvitationResponse -> "org.briarproject.briar.api.forum.ForumInvitationResponse"
is BlogInvitationResponse -> "org.briarproject.briar.api.blog.BlogInvitationResponse"
is GroupInvitationResponse -> "org.briarproject.briar.api.privategroup.invitation.GroupInvitationResponse"
else -> throw AssertionError("Unknown InvitationResponse")
}
val shareableId: ByteArray get() = iHeader.shareableId.bytes
internal fun BlogInvitationResponse.output(contactId: ContactId): Map<String, Any> {
val map: HashMap<String, Any> = hashMapOf(
"type" to "org.briarproject.briar.api.blog.BlogInvitationResponse"
)
map.putAll((this as InvitationResponse).output(contactId))
return map
}
internal fun PrivateResponse.output(contactId: ContactId): OutputPrivateMessage {
return when (this) {
is IntroductionResponse -> OutputIntroductionResponse(this, contactId)
is InvitationResponse -> OutputInvitationResponse(this, contactId)
else -> throw AssertionError("Unknown PrivateResponse")
}
internal fun ForumInvitationResponse.output(contactId: ContactId): Map<String, Any> {
val map: HashMap<String, Any> = hashMapOf(
"type" to "org.briarproject.briar.api.blog.BlogInvitationResponse"
)
map.putAll((this as InvitationResponse).output(contactId))
return map
}
internal fun GroupInvitationResponse.output(contactId: ContactId): Map<String, Any> {
val map: HashMap<String, Any> = hashMapOf(
"type" to "org.briarproject.briar.api.privategroup.invitation.GroupInvitationResponse"
)
map.putAll((this as InvitationResponse).output(contactId))
return map
}
\ No newline at end of file
......@@ -101,7 +101,7 @@ internal class BlogControllerTest : ControllerTest() {
fun testEmptyList() {
every { blogManager.blogs } returns listOf(blog)
every { blogManager.getPostHeaders(group.id) } returns emptyList()
every { ctx.json(emptyList<OutputBlogPost>()) } returns ctx
every { ctx.json(emptyList<Any>()) } returns ctx
controller.listPosts(ctx)
}
......
......@@ -14,7 +14,7 @@ internal class ContactControllerTest : ControllerTest() {
@Test
fun testEmptyContactList() {
every { contactManager.activeContacts } returns emptyList<Contact>()
every { ctx.json(emptyList<OutputContact>()) } returns ctx
every { ctx.json(emptyList<Any>()) } returns ctx
controller.list(ctx)
}
......
......@@ -55,7 +55,7 @@ internal class MessagingControllerImplTest : ControllerTest() {
every { ctx.pathParam("contactId") } returns contact.id.int.toString()
every { contactManager.getContact(contact.id) } returns contact
every { conversationManager.getMessageHeaders(contact.id) } returns emptyList<PrivateMessageHeader>()
every { ctx.json(emptyList<OutputPrivateMessageHeader>()) } returns ctx
every { ctx.json(emptyList<Any>()) } returns ctx
controller.list(ctx)
}
......@@ -73,7 +73,7 @@ internal class MessagingControllerImplTest : ControllerTest() {
@Test
fun write() {
val privateMessage = PrivateMessage(message)
val slot = CapturingSlot<OutputPrivateMessageHeader>()
val slot = CapturingSlot<Map<String, Any>>()
expectGetContact()
every { ctx.formParam("text") } returns body
......@@ -92,9 +92,9 @@ internal class MessagingControllerImplTest : ControllerTest() {
controller.write(ctx)
val output = slot.captured
assertEquals(contact.id.int, output.contactId)
assertEquals(body, output.body)
assertEquals(message.id.bytes, output.id)
assertEquals(contact.id.int, output.get("contactId"))
assertEquals(body, output.get("body"))
assertEquals(message.id.bytes, output.get("id"))
}
@Test
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment