Merge remote-tracking branch 'origin/master' into pairing_theo
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
package org.jeudego.pairgoth.api
|
||||
|
||||
import com.republicate.kson.Json
|
||||
import com.republicate.kson.toJsonObject
|
||||
import org.jeudego.pairgoth.api.ApiHandler.Companion.PAYLOAD_KEY
|
||||
import org.jeudego.pairgoth.api.ApiHandler.Companion.badRequest
|
||||
import org.jeudego.pairgoth.ext.OpenGotha
|
||||
@@ -21,7 +22,7 @@ object TournamentHandler: PairgothApiHandler {
|
||||
override fun get(request: HttpServletRequest, response: HttpServletResponse): Json? {
|
||||
val accept = request.getHeader("Accept")
|
||||
return when (val id = getSelector(request)?.toIntOrNull()) {
|
||||
null -> Json.Array(Store.getTournamentsIDs())
|
||||
null -> Store.getTournaments().toJsonObject()
|
||||
else ->
|
||||
when {
|
||||
ApiServlet.isJson(accept) -> Store.getTournament(id)?.toJson() ?: badRequest("no tournament with id #${id}")
|
||||
|
@@ -1,11 +1,8 @@
|
||||
package org.jeudego.pairgoth.model
|
||||
|
||||
import com.republicate.kson.Json
|
||||
import com.republicate.kson.toJsonArray
|
||||
import org.jeudego.pairgoth.api.ApiHandler
|
||||
import org.jeudego.pairgoth.api.ApiHandler.Companion.badRequest
|
||||
import org.jeudego.pairgoth.store.Store
|
||||
import kotlin.math.roundToInt
|
||||
|
||||
// Pairable
|
||||
|
||||
|
@@ -22,7 +22,7 @@ private fun Tournament<*>.filename() = "${id.toString().padStart(LEFT_PAD, '0')}
|
||||
|
||||
class FileStore(pathStr: String): StoreImplementation {
|
||||
companion object {
|
||||
private val filenameRegex = Regex("^(\\d+)-.*\\.tour$")
|
||||
private val filenameRegex = Regex("^(\\d+)-(.*)\\.tour$")
|
||||
private val timestampFormat: DateFormat = SimpleDateFormat("yyyyMMddHHmmss")
|
||||
private val timestamp: String get() = timestampFormat.format(Date())
|
||||
}
|
||||
@@ -33,14 +33,15 @@ class FileStore(pathStr: String): StoreImplementation {
|
||||
}
|
||||
|
||||
init {
|
||||
_nextTournamentId.set(getTournamentsIDs().maxOrNull() ?: 0.toID())
|
||||
_nextTournamentId.set(getTournaments().keys.maxOrNull() ?: 0.toID())
|
||||
}
|
||||
|
||||
override fun getTournamentsIDs(): Set<ID> {
|
||||
override fun getTournaments(): Map<ID, String> {
|
||||
return path.useDirectoryEntries("*.tour") { entries ->
|
||||
entries.mapNotNull { entry ->
|
||||
filenameRegex.matchEntire(entry.fileName.toString())?.groupValues?.get(1)?.toID()
|
||||
}.toSet()
|
||||
val match = filenameRegex.matchEntire(entry.fileName.toString())
|
||||
match?.let { Pair(it.groupValues[1].toID(), it.groupValues[2]) }
|
||||
}.sortedBy { it.first }.toMap()
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -6,7 +6,7 @@ import org.jeudego.pairgoth.model.Tournament
|
||||
class MemoryStore: StoreImplementation {
|
||||
private val tournaments = mutableMapOf<ID, Tournament<*>>()
|
||||
|
||||
override fun getTournamentsIDs(): Set<ID> = tournaments.keys
|
||||
override fun getTournaments(): Map<ID, String> = tournaments.mapValues { it.value.shortName }
|
||||
|
||||
override fun addTournament(tournament: Tournament<*>) {
|
||||
if (tournaments.containsKey(tournament.id)) throw Error("tournament id #${tournament.id} already exists")
|
||||
|
@@ -14,7 +14,7 @@ interface StoreImplementation {
|
||||
val nextPlayerId get() = _nextPlayerId.incrementAndGet()
|
||||
val nextGameId get() = _nextGameId.incrementAndGet()
|
||||
|
||||
fun getTournamentsIDs(): Set<ID>
|
||||
fun getTournaments(): Map<ID, String>
|
||||
fun addTournament(tournament: Tournament<*>)
|
||||
fun getTournament(id: ID): Tournament<*>?
|
||||
fun replaceTournament(tournament: Tournament<*>)
|
||||
|
@@ -170,7 +170,7 @@ class ApiServlet : HttpServlet() {
|
||||
}
|
||||
|
||||
// check charset
|
||||
if (charset != null && EXPECTED_CHARSET != charset) throw ApiException(
|
||||
if (charset != null && EXPECTED_CHARSET != charset.lowercase(Locale.ROOT).replace("-", "")) throw ApiException(
|
||||
HttpServletResponse.SC_BAD_REQUEST,
|
||||
"UTF-8 content expected"
|
||||
)
|
||||
@@ -215,6 +215,8 @@ class ApiServlet : HttpServlet() {
|
||||
HttpServletResponse.SC_BAD_REQUEST,
|
||||
"Missing 'Accept' header"
|
||||
)
|
||||
// CB TODO 1) a reference to a specific API call at this point is a code smell.
|
||||
// 2) there will e other content types: .tou, .h9, .html
|
||||
if (!isJson(accept) && (!isXml(accept) || !request.requestURI.matches(Regex("/api/tour/\\d+")))) throw ApiException(
|
||||
HttpServletResponse.SC_BAD_REQUEST,
|
||||
"Invalid 'Accept' header"
|
||||
|
@@ -51,7 +51,7 @@ class WebappManager : ServletContextListener, ServletContextAttributeListener, H
|
||||
/* ServletContextListener interface */
|
||||
override fun contextInitialized(sce: ServletContextEvent) {
|
||||
context = sce.servletContext
|
||||
logger.info("---------- Starting Web Application ----------")
|
||||
logger.info("---------- Starting Pairgoth Server ----------")
|
||||
context.setAttribute("manager", this)
|
||||
webappRoot = context.getRealPath("/")
|
||||
try {
|
||||
|
Reference in New Issue
Block a user