diff --git a/backend/src/main/kotlin/dev/dres/DRES.kt b/backend/src/main/kotlin/dev/dres/DRES.kt index 8ae051c29..0a59bc812 100644 --- a/backend/src/main/kotlin/dev/dres/DRES.kt +++ b/backend/src/main/kotlin/dev/dres/DRES.kt @@ -16,6 +16,7 @@ import dev.dres.data.model.template.team.DbTeamGroup import dev.dres.data.model.run.* import dev.dres.data.model.submissions.* import dev.dres.mgmt.MediaCollectionManager +import dev.dres.mgmt.TemplateManager import dev.dres.mgmt.admin.UserManager import dev.dres.mgmt.cache.CacheManager import dev.dres.run.RunExecutor @@ -106,6 +107,7 @@ object DRES { /* Initialize data managers */ UserManager.init(store) MediaCollectionManager.init(store) + TemplateManager.init(store) /* Initialize RunExecutor. */ RunExecutor.init(CONFIG, store, global) diff --git a/backend/src/main/kotlin/dev/dres/api/cli/EvaluationTemplateCommand.kt b/backend/src/main/kotlin/dev/dres/api/cli/EvaluationTemplateCommand.kt index f6a94e8ac..84c995a7d 100644 --- a/backend/src/main/kotlin/dev/dres/api/cli/EvaluationTemplateCommand.kt +++ b/backend/src/main/kotlin/dev/dres/api/cli/EvaluationTemplateCommand.kt @@ -15,7 +15,7 @@ import dev.dres.api.rest.types.template.ApiEvaluationTemplate import dev.dres.data.model.template.DbEvaluationTemplate import dev.dres.data.model.template.task.DbTaskTemplate import dev.dres.mgmt.cache.CacheManager -import dev.dres.utilities.TemplateUtil +import dev.dres.mgmt.TemplateManager import jetbrains.exodus.database.TransientEntityStore import kotlinx.dnq.query.* import org.joda.time.DateTime @@ -121,7 +121,7 @@ class EvaluationTemplateCommand(private val store: TransientEntityStore, private return@transactional } - TemplateUtil.copyTemplate(evaluationTemplate) + TemplateManager.copyTemplate(evaluationTemplate) println("template copied") } //println("Successfully copied template.") @@ -338,7 +338,7 @@ class EvaluationTemplateCommand(private val store: TransientEntityStore, private ) - TemplateUtil.updateDbTemplate(target, import) + TemplateManager.updateDbTemplate(target, import) println("template imported") } else { diff --git a/backend/src/main/kotlin/dev/dres/api/rest/RestApi.kt b/backend/src/main/kotlin/dev/dres/api/rest/RestApi.kt index ea57f962b..349cac554 100644 --- a/backend/src/main/kotlin/dev/dres/api/rest/RestApi.kt +++ b/backend/src/main/kotlin/dev/dres/api/rest/RestApi.kt @@ -123,15 +123,15 @@ object RestApi { ListExternalItemHandler(), // Template - ListEvaluationTemplatesHandler(store), - CreateEvaluationTemplateHandler(store), - UpdateEvaluationTemplateHandler(store, config), - ShowEvaluationTemplateHandler(store), - DeleteEvaluationTemplateHandler(store), - ListTeamHandler(store), - ListTasksHandler(store), + ListEvaluationTemplatesHandler(), + CreateEvaluationTemplateHandler(), + UpdateEvaluationTemplateHandler(), + ShowEvaluationTemplateHandler(), + DeleteEvaluationTemplateHandler(), + ListTeamHandler(), + ListTasksHandler(), ListTaskTypePresetsHandler(), - GetTeamLogoHandler(store), + GetTeamLogoHandler(), // Submission LegacySubmissionHandler(store, cache), diff --git a/backend/src/main/kotlin/dev/dres/api/rest/handler/template/AbstractEvaluationTemplateHandler.kt b/backend/src/main/kotlin/dev/dres/api/rest/handler/template/AbstractEvaluationTemplateHandler.kt index e5451fafb..6b85e0857 100644 --- a/backend/src/main/kotlin/dev/dres/api/rest/handler/template/AbstractEvaluationTemplateHandler.kt +++ b/backend/src/main/kotlin/dev/dres/api/rest/handler/template/AbstractEvaluationTemplateHandler.kt @@ -23,7 +23,7 @@ import kotlinx.dnq.query.query * @author Loris Sauter * @version 1.0.0 */ -abstract class AbstractEvaluationTemplateHandler(protected val store: TransientEntityStore) : RestHandler, AccessManagedRestHandler { +abstract class AbstractEvaluationTemplateHandler() : RestHandler, AccessManagedRestHandler { /** All [AbstractCollectionHandler]s require [ApiRole.ADMIN]. */ override val permittedRoles: Set = setOf(ApiRole.ADMIN) @@ -32,16 +32,16 @@ abstract class AbstractEvaluationTemplateHandler(protected val store: TransientE override val apiVersion = "v2" /** Convenience method to extract [DbEvaluationTemplate]'s ID from [Context]. */ - private fun templateIdFromContext(ctx: Context): TemplateId = + protected fun templateIdFromContext(ctx: Context): TemplateId = ctx.pathParamMap().getOrElse("templateId") { throw ErrorStatusException(404, "Parameter 'templateId' is missing!'", ctx) } - /** Convenience method to extract [DbEvaluationTemplate] from [Context]. */ - protected fun evaluationTemplateFromContext(ctx: Context): DbEvaluationTemplate - = evaluationTemplateById(templateIdFromContext(ctx), ctx) - - /** Convenience method to extract [DbEvaluationTemplate] by ID. */ - protected fun evaluationTemplateById(id: TemplateId, ctx: Context): DbEvaluationTemplate - = DbEvaluationTemplate.query((DbEvaluationTemplate::id) eq id and (DbEvaluationTemplate::instance eq false)).firstOrNull() ?: throw ErrorStatusException(404, "Evaluation template with ID $id not found.'", ctx) +// /** Convenience method to extract [DbEvaluationTemplate] from [Context]. */ +// protected fun evaluationTemplateFromContext(ctx: Context): DbEvaluationTemplate +// = evaluationTemplateById(templateIdFromContext(ctx), ctx) +// +// /** Convenience method to extract [DbEvaluationTemplate] by ID. */ +// protected fun evaluationTemplateById(id: TemplateId, ctx: Context): DbEvaluationTemplate +// = DbEvaluationTemplate.query((DbEvaluationTemplate::id) eq id and (DbEvaluationTemplate::instance eq false)).firstOrNull() ?: throw ErrorStatusException(404, "Evaluation template with ID $id not found.'", ctx) } diff --git a/backend/src/main/kotlin/dev/dres/api/rest/handler/template/CreateEvaluationTemplateHandler.kt b/backend/src/main/kotlin/dev/dres/api/rest/handler/template/CreateEvaluationTemplateHandler.kt index 3485cea38..d14de7e8b 100644 --- a/backend/src/main/kotlin/dev/dres/api/rest/handler/template/CreateEvaluationTemplateHandler.kt +++ b/backend/src/main/kotlin/dev/dres/api/rest/handler/template/CreateEvaluationTemplateHandler.kt @@ -6,6 +6,7 @@ import dev.dres.api.rest.types.status.ErrorStatus import dev.dres.api.rest.types.status.ErrorStatusException import dev.dres.api.rest.types.status.SuccessStatus import dev.dres.data.model.template.DbEvaluationTemplate +import dev.dres.mgmt.TemplateManager import io.javalin.http.BadRequestResponse import io.javalin.http.Context import io.javalin.http.bodyAsClass @@ -22,7 +23,7 @@ import java.util.* * @author Loris Sauter * @version 2.0.0 */ -class CreateEvaluationTemplateHandler(store: TransientEntityStore) : AbstractEvaluationTemplateHandler(store), PostRestHandler { +class CreateEvaluationTemplateHandler : AbstractEvaluationTemplateHandler(), PostRestHandler { override val route: String = "template" @@ -47,17 +48,8 @@ class CreateEvaluationTemplateHandler(store: TransientEntityStore) : AbstractEva throw ErrorStatusException(400, "Invalid parameters. This is a programmers error!", ctx) } - val newId = UUID.randomUUID().toString() - this.store.transactional { - DbEvaluationTemplate.new { - this.id = newId - this.instance = false - this.name = createRequest.name - this.description = createRequest.description - this.created = DateTime.now() - this.modified = DateTime.now() - } - } - return SuccessStatus("Evaluation template with ID $newId was created successfully.") + val template = TemplateManager.createEvaluationTemplate(createRequest.name, createRequest.description) + + return SuccessStatus("Evaluation template with ID ${template.id} was created successfully.") } } diff --git a/backend/src/main/kotlin/dev/dres/api/rest/handler/template/DeleteEvaluationTemplateHandler.kt b/backend/src/main/kotlin/dev/dres/api/rest/handler/template/DeleteEvaluationTemplateHandler.kt index b25f7668e..24781ed88 100644 --- a/backend/src/main/kotlin/dev/dres/api/rest/handler/template/DeleteEvaluationTemplateHandler.kt +++ b/backend/src/main/kotlin/dev/dres/api/rest/handler/template/DeleteEvaluationTemplateHandler.kt @@ -5,6 +5,7 @@ import dev.dres.api.rest.types.status.ErrorStatus import dev.dres.api.rest.types.status.ErrorStatusException import dev.dres.api.rest.types.status.SuccessStatus import dev.dres.data.model.template.DbEvaluationTemplate +import dev.dres.mgmt.TemplateManager import io.javalin.http.Context import io.javalin.openapi.* import jetbrains.exodus.database.TransientEntityStore @@ -17,7 +18,7 @@ import jetbrains.exodus.database.TransientEntityStore * @author Loris Sauter * @version 2.0.0 */ -class DeleteEvaluationTemplateHandler(store: TransientEntityStore) : AbstractEvaluationTemplateHandler(store), DeleteRestHandler { +class DeleteEvaluationTemplateHandler : AbstractEvaluationTemplateHandler(), DeleteRestHandler { override val route: String = "template/{templateId}" @OpenApi( @@ -34,10 +35,13 @@ class DeleteEvaluationTemplateHandler(store: TransientEntityStore) : AbstractEva OpenApiResponse("404", [OpenApiContent(ErrorStatus::class)]) ] ) - override fun doDelete(ctx: Context): SuccessStatus = this.store.transactional { - val template = evaluationTemplateFromContext(ctx) - template.delete() - SuccessStatus("Evaluation template with ID ${ctx.pathParam("templateId")} was deleted successfully.") + override fun doDelete(ctx: Context): SuccessStatus { + val template = TemplateManager.deleteTemplate(templateIdFromContext(ctx)) + if (template != null) { + return SuccessStatus("Evaluation template with ID ${template.id} was deleted successfully.") + } else { + throw ErrorStatusException(404, "Template not found", ctx) + } } } diff --git a/backend/src/main/kotlin/dev/dres/api/rest/handler/template/GetTeamLogoHandler.kt b/backend/src/main/kotlin/dev/dres/api/rest/handler/template/GetTeamLogoHandler.kt index e73ad7504..4b050be74 100644 --- a/backend/src/main/kotlin/dev/dres/api/rest/handler/template/GetTeamLogoHandler.kt +++ b/backend/src/main/kotlin/dev/dres/api/rest/handler/template/GetTeamLogoHandler.kt @@ -4,6 +4,7 @@ import dev.dres.api.rest.handler.GetRestHandler import dev.dres.api.rest.types.status.ErrorStatusException import dev.dres.api.rest.types.users.ApiRole import dev.dres.data.model.template.team.DbTeam +import dev.dres.mgmt.TemplateManager import io.javalin.http.Context import io.javalin.openapi.* import io.javalin.security.RouteRole @@ -20,7 +21,7 @@ import kotlinx.dnq.query.query * @author Loris Sauter * @version 1.0.0 */ -class GetTeamLogoHandler(store: TransientEntityStore) : AbstractEvaluationTemplateHandler(store), GetRestHandler { +class GetTeamLogoHandler : AbstractEvaluationTemplateHandler(), GetRestHandler { override val route = "template/logo/{teamId}" override val apiVersion = "v2" @@ -29,7 +30,8 @@ class GetTeamLogoHandler(store: TransientEntityStore) : AbstractEvaluationTempla override fun doGet(ctx: Context): Any = "" /** All authorised users can access the team logo. */ - override val permittedRoles: Set = setOf(ApiRole.PARTICIPANT, ApiRole.VIEWER, ApiRole.JUDGE, ApiRole.ADMIN) + override val permittedRoles: Set = + setOf(ApiRole.PARTICIPANT, ApiRole.VIEWER, ApiRole.JUDGE, ApiRole.ADMIN) @OpenApi( summary = "Returns the logo for the given team ID.", @@ -43,17 +45,17 @@ class GetTeamLogoHandler(store: TransientEntityStore) : AbstractEvaluationTempla ) override fun get(ctx: Context) { /* Extract logoId. */ - val teamId = ctx.pathParamMap()["teamId"] ?: throw ErrorStatusException(400, "Parameter 'teamId' is missing!'", ctx) - this.store.transactional(true) { - val logo = DbTeam.query(DbTeam::id eq teamId).firstOrNull()?.logo - if (logo != null) { - ctx.contentType("image/png") - ctx.result(logo) - } else { - ctx.status(404) - ctx.contentType("image/png") - ctx.result(this.javaClass.getResourceAsStream("/img/missing.png")!!) - } + val teamId = + ctx.pathParamMap()["teamId"] ?: throw ErrorStatusException(400, "Parameter 'teamId' is missing!'", ctx) + ctx.contentType("image/png") + + val logo = TemplateManager.getTeamLogo(teamId) + if (logo != null) { + ctx.result(logo) + } else { + ctx.status(404) + ctx.result(this.javaClass.getResourceAsStream("/img/missing.png")!!) } + } } diff --git a/backend/src/main/kotlin/dev/dres/api/rest/handler/template/ListEvaluationTemplatesHandler.kt b/backend/src/main/kotlin/dev/dres/api/rest/handler/template/ListEvaluationTemplatesHandler.kt index 7887a38d2..7b11fd664 100644 --- a/backend/src/main/kotlin/dev/dres/api/rest/handler/template/ListEvaluationTemplatesHandler.kt +++ b/backend/src/main/kotlin/dev/dres/api/rest/handler/template/ListEvaluationTemplatesHandler.kt @@ -4,6 +4,7 @@ import dev.dres.api.rest.handler.GetRestHandler import dev.dres.api.rest.types.template.ApiEvaluationTemplateOverview import dev.dres.api.rest.types.status.ErrorStatus import dev.dres.data.model.template.DbEvaluationTemplate +import dev.dres.mgmt.TemplateManager import io.javalin.http.Context import io.javalin.openapi.* import jetbrains.exodus.database.TransientEntityStore @@ -20,7 +21,7 @@ import kotlinx.dnq.query.size * @author Loris Sauter * @version 2.0.0 */ -class ListEvaluationTemplatesHandler(store: TransientEntityStore) : AbstractEvaluationTemplateHandler(store), GetRestHandler> { +class ListEvaluationTemplatesHandler() : AbstractEvaluationTemplateHandler(), GetRestHandler> { override val route: String = "template/list" @OpenApi( @@ -34,9 +35,5 @@ class ListEvaluationTemplatesHandler(store: TransientEntityStore) : AbstractEval ], methods = [HttpMethod.GET] ) - override fun doGet(ctx: Context) = this.store.transactional(true) { - DbEvaluationTemplate.query(DbEvaluationTemplate::instance eq false).asSequence().map { - ApiEvaluationTemplateOverview(it.id, it.name, it.description, it.tasks.size(), it.teams.size()) - }.toList() - } + override fun doGet(ctx: Context) = TemplateManager.getTemplateOverview() } diff --git a/backend/src/main/kotlin/dev/dres/api/rest/handler/template/ListTasksHandler.kt b/backend/src/main/kotlin/dev/dres/api/rest/handler/template/ListTasksHandler.kt index 4732774d5..066ea539b 100644 --- a/backend/src/main/kotlin/dev/dres/api/rest/handler/template/ListTasksHandler.kt +++ b/backend/src/main/kotlin/dev/dres/api/rest/handler/template/ListTasksHandler.kt @@ -3,7 +3,9 @@ package dev.dres.api.rest.handler.template import dev.dres.api.rest.handler.GetRestHandler import dev.dres.api.rest.types.template.tasks.ApiTaskTemplate import dev.dres.api.rest.types.status.ErrorStatus +import dev.dres.api.rest.types.status.ErrorStatusException import dev.dres.data.model.template.task.DbTaskTemplate +import dev.dres.mgmt.TemplateManager import io.javalin.http.Context import io.javalin.openapi.* import jetbrains.exodus.database.TransientEntityStore @@ -18,7 +20,7 @@ import kotlinx.dnq.query.filter * @author Loris Sauter * @version 2.0.0 */ -class ListTasksHandler(store: TransientEntityStore) : AbstractEvaluationTemplateHandler(store), GetRestHandler> { +class ListTasksHandler() : AbstractEvaluationTemplateHandler(), GetRestHandler> { override val route: String = "template/{templateId}/task/list" @@ -39,8 +41,6 @@ class ListTasksHandler(store: TransientEntityStore) : AbstractEvaluationTemplate override fun doGet(ctx: Context): List { val templateId = ctx.pathParam("templateId") - return this.store.transactional(true) { - DbTaskTemplate.filter { it.evaluation.id eq templateId }.asSequence().map { it.toApi() }.toList() - } + return TemplateManager.getTemplate(templateId)?.tasks ?: throw ErrorStatusException(404, "Template with id '$templateId' not found.", ctx) } } diff --git a/backend/src/main/kotlin/dev/dres/api/rest/handler/template/ListTeamHandler.kt b/backend/src/main/kotlin/dev/dres/api/rest/handler/template/ListTeamHandler.kt index ca1f3750a..1cac72e49 100644 --- a/backend/src/main/kotlin/dev/dres/api/rest/handler/template/ListTeamHandler.kt +++ b/backend/src/main/kotlin/dev/dres/api/rest/handler/template/ListTeamHandler.kt @@ -3,7 +3,9 @@ package dev.dres.api.rest.handler.template import dev.dres.api.rest.handler.GetRestHandler import dev.dres.api.rest.types.template.team.ApiTeam import dev.dres.api.rest.types.status.ErrorStatus +import dev.dres.api.rest.types.status.ErrorStatusException import dev.dres.data.model.template.team.DbTeam +import dev.dres.mgmt.TemplateManager import io.javalin.http.Context import io.javalin.openapi.* import jetbrains.exodus.database.TransientEntityStore @@ -18,7 +20,7 @@ import kotlinx.dnq.query.filter * @author Loris Sauter * @version 2.0.0 */ -class ListTeamHandler(store: TransientEntityStore) : AbstractEvaluationTemplateHandler(store), GetRestHandler> { +class ListTeamHandler : AbstractEvaluationTemplateHandler(), GetRestHandler> { override val route: String = "template/{templateId}/team/list" @@ -39,8 +41,6 @@ class ListTeamHandler(store: TransientEntityStore) : AbstractEvaluationTemplateH override fun doGet(ctx: Context): List { val templateId = ctx.pathParam("templateId") - return this.store.transactional(true) { - DbTeam.filter { it.evaluation.id eq templateId }.asSequence().map { it.toApi() }.toList() - } + return TemplateManager.getTemplate(templateId)?.teams ?: throw ErrorStatusException(404, "Template with id '$templateId' not found.", ctx) } } diff --git a/backend/src/main/kotlin/dev/dres/api/rest/handler/template/ShowEvaluationTemplateHandler.kt b/backend/src/main/kotlin/dev/dres/api/rest/handler/template/ShowEvaluationTemplateHandler.kt index 968dd75f5..1649a31ad 100644 --- a/backend/src/main/kotlin/dev/dres/api/rest/handler/template/ShowEvaluationTemplateHandler.kt +++ b/backend/src/main/kotlin/dev/dres/api/rest/handler/template/ShowEvaluationTemplateHandler.kt @@ -3,7 +3,9 @@ package dev.dres.api.rest.handler.template import dev.dres.api.rest.handler.GetRestHandler import dev.dres.api.rest.types.template.ApiEvaluationTemplate import dev.dres.api.rest.types.status.ErrorStatus +import dev.dres.api.rest.types.status.ErrorStatusException import dev.dres.data.model.template.DbEvaluationTemplate +import dev.dres.mgmt.TemplateManager import io.javalin.http.Context import io.javalin.openapi.* import jetbrains.exodus.database.TransientEntityStore @@ -16,7 +18,7 @@ import jetbrains.exodus.database.TransientEntityStore * @author Loris Sauter * @version 2.0.0 */ -class ShowEvaluationTemplateHandler(store: TransientEntityStore) : AbstractEvaluationTemplateHandler(store), GetRestHandler { +class ShowEvaluationTemplateHandler : AbstractEvaluationTemplateHandler(), GetRestHandler { override val route: String = "template/{templateId}" @OpenApi( @@ -33,7 +35,5 @@ class ShowEvaluationTemplateHandler(store: TransientEntityStore) : AbstractEvalu ], methods = [HttpMethod.GET] ) - override fun doGet(ctx: Context)= this.store.transactional(true) { - evaluationTemplateFromContext(ctx).toApi() - } + override fun doGet(ctx: Context) = TemplateManager.getTemplate(templateIdFromContext(ctx)) ?: throw ErrorStatusException(404, "Evaluation template not found.'", ctx) } diff --git a/backend/src/main/kotlin/dev/dres/api/rest/handler/template/UpdateEvaluationTemplateHandler.kt b/backend/src/main/kotlin/dev/dres/api/rest/handler/template/UpdateEvaluationTemplateHandler.kt index 72033b2bc..fe5abd75d 100644 --- a/backend/src/main/kotlin/dev/dres/api/rest/handler/template/UpdateEvaluationTemplateHandler.kt +++ b/backend/src/main/kotlin/dev/dres/api/rest/handler/template/UpdateEvaluationTemplateHandler.kt @@ -2,29 +2,16 @@ package dev.dres.api.rest.handler.template import dev.dres.api.rest.handler.PatchRestHandler import dev.dres.api.rest.types.template.ApiEvaluationTemplate -import dev.dres.api.rest.types.template.tasks.ApiTargetType import dev.dres.api.rest.types.status.ErrorStatus import dev.dres.api.rest.types.status.ErrorStatusException import dev.dres.api.rest.types.status.SuccessStatus import dev.dres.data.model.config.Config -import dev.dres.data.model.admin.DbUser -import dev.dres.data.model.media.DbMediaCollection import dev.dres.data.model.template.DbEvaluationTemplate -import dev.dres.data.model.template.task.* -import dev.dres.data.model.template.task.options.DbConfiguredOption -import dev.dres.data.model.template.team.DbTeam -import dev.dres.data.model.template.team.DbTeamGroup -import dev.dres.data.model.media.DbMediaItem -import dev.dres.utilities.TemplateUtil +import dev.dres.mgmt.TemplateManager import io.javalin.http.BadRequestResponse import io.javalin.http.Context import io.javalin.openapi.* import jetbrains.exodus.database.TransientEntityStore -import kotlinx.dnq.creator.findOrNew -import kotlinx.dnq.query.* -import kotlinx.dnq.util.getSafe -import org.joda.time.DateTime -import kotlin.time.ExperimentalTime /** * A [AbstractEvaluationTemplateHandler] that can be used to create a new [DbEvaluationTemplate]. @@ -34,8 +21,8 @@ import kotlin.time.ExperimentalTime * @author Loris Sauter * @version 2.1.0 */ -class UpdateEvaluationTemplateHandler(store: TransientEntityStore, val config: Config) : - AbstractEvaluationTemplateHandler(store), PatchRestHandler { +class UpdateEvaluationTemplateHandler : + AbstractEvaluationTemplateHandler(), PatchRestHandler { override val route: String = "template/{templateId}" @@ -68,20 +55,17 @@ class UpdateEvaluationTemplateHandler(store: TransientEntityStore, val config: C throw ErrorStatusException(400, "Invalid parameters. This is a programmers error!", ctx) } - /* Store change. */ - this.store.transactional { - val existing = this.evaluationTemplateById(apiValue.id, ctx) - if (existing.modified?.millis != apiValue.modified) { - throw ErrorStatusException(409, "Evaluation template ${apiValue.id} has been modified in the meantime. Reload and try again!", ctx) - } - - try { - TemplateUtil.updateDbTemplate(existing, apiValue) - } catch (e: IllegalArgumentException) { - throw ErrorStatusException(404, e.message ?: "", ctx) - } + val existing = TemplateManager.getTemplate(apiValue.id) ?: throw ErrorStatusException(404, "Template with id '' not found", ctx) + if (existing.modified != apiValue.modified) { + throw ErrorStatusException(409, "Evaluation template ${apiValue.id} has been modified in the meantime. Reload and try again!", ctx) + } + try { + TemplateManager.updateDbTemplate(apiValue) + } catch (e: IllegalArgumentException) { + throw ErrorStatusException(404, e.message ?: "", ctx) } + return SuccessStatus("Evaluation template with ID ${apiValue.id} was updated successfully.") } } diff --git a/backend/src/main/kotlin/dev/dres/utilities/TemplateUtil.kt b/backend/src/main/kotlin/dev/dres/mgmt/TemplateManager.kt similarity index 82% rename from backend/src/main/kotlin/dev/dres/utilities/TemplateUtil.kt rename to backend/src/main/kotlin/dev/dres/mgmt/TemplateManager.kt index c7aa23df9..e66ea1fb8 100644 --- a/backend/src/main/kotlin/dev/dres/utilities/TemplateUtil.kt +++ b/backend/src/main/kotlin/dev/dres/mgmt/TemplateManager.kt @@ -1,6 +1,7 @@ -package dev.dres.utilities +package dev.dres.mgmt import dev.dres.api.rest.types.template.ApiEvaluationTemplate +import dev.dres.api.rest.types.template.ApiEvaluationTemplateOverview import dev.dres.api.rest.types.template.tasks.ApiTargetType import dev.dres.data.model.admin.DbUser import dev.dres.data.model.media.DbMediaCollection @@ -11,19 +12,72 @@ import dev.dres.data.model.template.task.* import dev.dres.data.model.template.task.options.DbConfiguredOption import dev.dres.data.model.template.team.DbTeam import dev.dres.data.model.template.team.DbTeamGroup +import dev.dres.data.model.template.team.TeamId +import jetbrains.exodus.database.TransientEntityStore import kotlinx.dnq.creator.findOrNew import kotlinx.dnq.query.* import kotlinx.dnq.util.getSafe import org.joda.time.DateTime +import java.io.InputStream -object TemplateUtil { +object TemplateManager { + + private lateinit var store: TransientEntityStore + + fun init(store: TransientEntityStore) { + this.store = store + } + + fun createEvaluationTemplate(name: String, description: String): ApiEvaluationTemplate = this.store.transactional { + val template = DbEvaluationTemplate.new { + this.instance = false + this.name = name + this.description = description + this.created = DateTime.now() + this.modified = DateTime.now() + } + template.toApi() + } + + fun deleteTemplate(templateId: TemplateId): ApiEvaluationTemplate? = this.store.transactional { + val template = + DbEvaluationTemplate.query((DbEvaluationTemplate::id) eq templateId and (DbEvaluationTemplate::instance eq false)) + .firstOrNull() ?: return@transactional null + val api = template.toApi() + template.delete() + api + } + + fun getTemplateOverview(): List = this.store.transactional(true) { + DbEvaluationTemplate.query(DbEvaluationTemplate::instance eq false).asSequence().map { + ApiEvaluationTemplateOverview(it.id, it.name, it.description, it.tasks.size(), it.teams.size()) + }.toList() + } + + fun getTemplate(templateId: TemplateId): ApiEvaluationTemplate? = this.store.transactional(true) { + DbEvaluationTemplate.query((DbEvaluationTemplate::id) eq templateId and (DbEvaluationTemplate::instance eq false)) + .firstOrNull()?.toApi() + } + + fun getTeamLogo(teamId: TeamId) : InputStream? = this.store.transactional(true) { + DbTeam.query(DbTeam::id eq teamId).firstOrNull()?.logo + } /** - * Writes the state of an [ApiEvaluationTemplate] into an existing [DbEvaluationTemplate]. + * Writes the state of an [ApiEvaluationTemplate]. * Requires a transaction context. */ + fun updateDbTemplate(apiEvaluationTemplate: ApiEvaluationTemplate) { + + val dbEvaluationTemplate = + DbEvaluationTemplate.query((DbEvaluationTemplate::id) eq apiEvaluationTemplate.id and (DbEvaluationTemplate::instance eq false)) + .firstOrNull() ?: throw IllegalArgumentException("No template with id '${apiEvaluationTemplate.id}'") + + updateDbTemplate(dbEvaluationTemplate, apiEvaluationTemplate) + } + @Throws(IllegalArgumentException::class) - fun updateDbTemplate(dbEvaluationTemplate: DbEvaluationTemplate, apiEvaluationTemplate: ApiEvaluationTemplate) { + fun updateDbTemplate(dbEvaluationTemplate: DbEvaluationTemplate, apiEvaluationTemplate: ApiEvaluationTemplate) = this.store.transactional { /* Update core information. */ @@ -158,7 +212,6 @@ object TemplateUtil { } - /* Update team information. */ val teamIds = apiEvaluationTemplate.teams.map { it.id }.toTypedArray() dbEvaluationTemplate.teams.removeAll(