Skip to content

Commit

Permalink
Implement participant rest controller
Browse files Browse the repository at this point in the history
  • Loading branch information
BilledTrain380 committed Aug 1, 2018
1 parent 6b98a3e commit c603743
Show file tree
Hide file tree
Showing 9 changed files with 498 additions and 101 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -70,4 +70,12 @@ interface ClassManager {
* @param clazz the class to save
*/
fun saveClass(clazz: Clazz)

/**
* A pending participation means, if any participant of the given {@code clazz}
* as no sport.
*
* @return true if the class has pending participation, otherwise false
*/
fun hasPendingParticipation(clazz: Clazz): Boolean
}
Original file line number Diff line number Diff line change
Expand Up @@ -90,12 +90,17 @@ class DefaultClassManager(
TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
}

private fun ClazzEntity.pendingParticipation() = competitorRepository.findByClazzName(this.name).any { it.sport == null }
/**
* A pending participation means, if any participant of the given {@code clazz}
* as no sport.
*
* @return true if the class has pending participation, otherwise false
*/
override fun hasPendingParticipation(clazz: Clazz) = competitorRepository.findByClazzName(clazz.name).any { it.sport == null }

private fun ClazzEntity.map(): Clazz {
return Clazz(
name,
Coach(coach.id!!, coach.name),
pendingParticipation())
Coach(coach.id!!, coach.name))
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,151 @@
/*
* Copyright (c) 2018 by Nicolas Märchy
*
* This file is part of Sporttag PSA.
*
* Sporttag PSA is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Sporttag PSA is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Sporttag PSA. If not, see <http://www.gnu.org/licenses/>.
*
* Diese Datei ist Teil von Sporttag PSA.
*
* Sporttag PSA ist Freie Software: Sie können es unter den Bedingungen
* der GNU General Public License, wie von der Free Software Foundation,
* Version 3 der Lizenz oder (nach Ihrer Wahl) jeder späteren
* veröffentlichten Version, weiterverbreiten und/oder modifizieren.
*
* Sporttag PSA wird in der Hoffnung, dass es nützlich sein wird, aber
* OHNE JEDE GEWÄHRLEISTUNG, bereitgestellt; sogar ohne die implizite
* Gewährleistung der MARKTFÄHIGKEIT oder EIGNUNG FÜR EINEN BESTIMMTEN ZWECK.
* Siehe die GNU General Public License für weitere Details.
*
* Sie sollten eine Kopie der GNU General Public License zusammen mit diesem
* Programm erhalten haben. Wenn nicht, siehe <http://www.gnu.org/licenses/>.
*
*
*/

package ch.schulealtendorf.sporttagpsa.controller.rest

import javax.validation.constraints.NotNull

/*
* Because POJOs for Spring Rest Controller needs to have a default parameter
* and we can validate our POJOs with Spring Annotations, we make every property nullable
* and initialize it with null (like in Java where null-safe does not exist).
*
* If a property is required we annotate it with @NotNull, in order to validate it with Spring.
*/

/**
* @author nmaerchy <billedtrain380@gmail.com>
* @since 2.0.0
*/
data class RestClass(

@NotNull
var name: String? = null,

@NotNull
var coach: String? = null,

@NotNull
var pendingParticipation: Boolean? = null
)

/**
* @author nmaerchy <billedtrain380@gmail.com>
* @since 2.0.0
*/
data class RestTown(

@NotNull
var id: Int? = null,

@NotNull
var zip: String? = null,

@NotNull
var name: String? = null
)

/**
* @author nmaerchy <billedtrain380@gmail.com>
* @since 2.0.0
*/
data class RestParticipant(

@NotNull
var id: Int? = null,

@NotNull
var surname: String? = null,

@NotNull
var prename: String? = null,

@NotNull
var gender: Boolean? = null,

@NotNull
var birthday: Long? = null,

@NotNull
var absent: Boolean? = null,

@NotNull
var address: String? = null,

@NotNull
var town: RestTown? = null,

@NotNull
var clazz: RestClass? = null,

@NotNull
var sport: String? = null
)

/**
* @author nmaerchy <billedtrain380@gmail.com>
* @since 2.0.0
*/
data class RestPutParticipant(

@NotNull
var surname: String? = null,

@NotNull
var prename: String? = null,

@NotNull
var gender: Boolean? = null,

@NotNull
var birthday: Long? = null,

@NotNull
var address: String? = null,

@NotNull
var absent: Boolean? = null
)

/**
* @author nmaerchy <billedtrain380@gmail.com>
* @since 2.0.0
*/
data class RestPatchParticipant(
var town: RestTown? = null,
var clazz: RestClass? = null,
var sport: String? = null
)
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ package ch.schulealtendorf.sporttagpsa.controller.rest.clazz

import ch.schulealtendorf.sporttagpsa.business.clazz.ClassManager
import ch.schulealtendorf.sporttagpsa.controller.rest.BadRequestException
import ch.schulealtendorf.sporttagpsa.controller.rest.RestClass
import ch.schulealtendorf.sporttagpsa.model.Clazz
import org.springframework.http.MediaType
import org.springframework.web.bind.annotation.GetMapping
Expand All @@ -56,12 +57,24 @@ class ClassController(
) {

@GetMapping("/classes", produces = [MediaType.APPLICATION_JSON_VALUE])
fun getAllClasses() = classManager.getAllClasses()
fun getAllClasses(): List<RestClass> {
return classManager.getAllClasses()
.map { it.map() }
}

@GetMapping("/class/{class_id}", produces = [MediaType.APPLICATION_JSON_VALUE])
fun getClass(@PathVariable("class_id") classId: String): Clazz {
fun getClass(@PathVariable("class_id") classId: String): RestClass {

val clazz = classManager.getClass(classId).orElseThrow { BadRequestException("Could not find class with id '$classId'") }

return clazz.map()
}

val clazz = classManager.getClass(classId)
return clazz.orElseThrow { BadRequestException("Could not find class with id '$classId'") }
private fun Clazz.map(): RestClass {
return RestClass(
name,
coach.name,
classManager.hasPendingParticipation(this)
)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -36,16 +36,154 @@

package ch.schulealtendorf.sporttagpsa.controller.rest.participant

import org.springframework.web.bind.annotation.RestController
import ch.schulealtendorf.sporttagpsa.business.clazz.ClassManager
import ch.schulealtendorf.sporttagpsa.business.participant.ParticipantManager
import ch.schulealtendorf.sporttagpsa.controller.rest.*
import ch.schulealtendorf.sporttagpsa.model.*
import org.springframework.http.MediaType
import org.springframework.web.bind.annotation.*
import javax.validation.Valid

/**
* Rest controller for the participants.
*
* @author nmaerchy <billedtrain380@gmail.com>
* @since 2.0.0
*/
@RestController
class ParticipantController() {
class ParticipantController(
private val participantManager: ParticipantManager,
private val classManager: ClassManager
) {

@GetMapping("/participants", produces = [MediaType.APPLICATION_JSON_VALUE])
fun getAllParticipants(@RequestParam("class", required = false) clazzName: String?): List<RestParticipant> {

if (clazzName == null) {
return participantManager.getAllParticipants().map { it.map() }
}

val clazz = classManager.getClass(clazzName).orElseThrow { BadRequestException("Could not find class with name '$clazzName'") }

return participantManager.getAllParticipants(clazz).map { it.map() }
}

@PostMapping("/participant")
fun addParticipant() {
TODO("This request is not supported yet")
}

@GetMapping("/participant/{participant_id}")
fun getParticipant(@PathVariable("participant_id") participantId: Int): RestParticipant {

return participantManager.getParticipant(participantId)
.map { it.map() }
.orElseThrow { BadRequestException("Could not find participant with id '$participantId'") }
}

@PutMapping("/participant/{participant_id}")
fun updateParticipant(@PathVariable("participant_id") participantId: Int, @Valid @RequestBody restParticipant: RestPutParticipant) {

val participant = participantManager.getParticipant(participantId)
.orElseThrow { BadRequestException("Could not find participant with id '$participantId'") }

val updatedParticipant = participant.copy(
surname = restParticipant.surname!!,
prename = restParticipant.prename!!,
gender = Gender(restParticipant.absent!!),
birthday = Birthday(restParticipant.birthday!!),
address = restParticipant.address!!,
absent = restParticipant.absent!!
)

participantManager.saveParticipant(updatedParticipant)
}

@PatchMapping("/participant/{participant_id}")
fun updateParticipant(@PathVariable("participant_id") participantId: Int, @Valid @RequestBody restParticipant: RestPatchParticipant) {

if (restParticipant.clazz == null && restParticipant.town == null && restParticipant.sport == null) {
throw BadRequestException("Missing either 'clazz', 'town' or 'sport' in request body.")
}

val participant = participantManager.getParticipant(participantId)
.orElseThrow { BadRequestException("Could not find participant with id '$participantId'") }

if (restParticipant.clazz != null) {
val clazz = classManager.getClass(restParticipant.clazz!!.name!!)
.orElseThrow { BadRequestException("Could not find class with name''${restParticipant.clazz!!.name}") }
participant.update(clazz)
}

if (restParticipant.sport != null) {
participant.update(restParticipant.sport!!)
}

if (restParticipant.town != null) {
participant.update(restParticipant.town!!)
}
}

private fun Participant.update(sport: String) {
participantManager.saveParticipant(
this.copy(
sport = java.util.Optional.of(sport)
)
)
}

private fun Participant.update(town: RestTown) {
participantManager.saveParticipant(
this.copy(
town = town.map()
)
)
}

private fun Participant.update(clazz: Clazz) {
participantManager.saveParticipant(
this.copy(
clazz = clazz
)
)
}

private fun Participant.map(): RestParticipant {
return RestParticipant(
id,
surname,
prename,
gender.value,
birthday.milliseconds,
absent,
address,
town.map(),
clazz.map(),
sport.orElse(null)
)
}

private fun Clazz.map(): RestClass {
return RestClass(
name,
coach.name,
classManager.hasPendingParticipation(this)
)
}

private fun Town.map(): RestTown {
return RestTown(
id,
zip,
name
)
}

fun getAllParticipants(): List<RestParticipant> {
TODO("not implemented yet")
private fun RestTown.map(): Town {
return Town(
id!!,
zip!!,
name!!
)
}
}
Loading

0 comments on commit c603743

Please sign in to comment.