Commit 20fc2363 authored by Günter Hipler's avatar Günter Hipler
Browse files

more refactoring: putting a lot of derived sealed classes into dedicated

files to provide people coming from outside an easier understanding for
the implementation
parent b5b622aa
Pipeline #23461 passed with stage
in 2 minutes and 29 seconds
......@@ -32,10 +32,6 @@ import play.api.mvc.{AbstractController, Action, AnyContent, ControllerComponent
class OaiController @Inject()(cc: ControllerComponents)
(implicit config: Configuration,repository:OaiRepository ) extends AbstractController(cc) with Rendering {
//todo: better way might be to use a so called BindController - have a look into this type part of this package
// where I played around a little bit with it
//https://www.playframework.com/documentation/2.8.x/RequestBinders
//todo: can we make the Action more type specific (not AnyContent)
def handleRequest(verb: Option[String],
metadataPrefix: Option[String],
......
/*
* generic OAI Server - agnostic in relation to the data repository
* initially created for memobase project
*
* Copyright (C) 2021 UB Basel
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program 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 Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*
*/
package org.swissbib.memobase.oai.response
import com.typesafe.config.ConfigObject
import modules.OaiRepository
import org.swissbib.memobase.oai.common.validation.BadArgumentsParameter
import play.api.Configuration
import scala.collection.immutable
import scala.xml.{Elem, Node}
import scala.xml.transform.{RewriteRule, RuleTransformer}
case class BadArgumentsResponse(config: Configuration
,repository: OaiRepository
,parameter: BadArgumentsParameter) extends OaiResponse (repository.oaiConfig
,parameter) {
override def toString: String = s"Ich bin eine BadArguments response "
override def createResponse: Seq[Node] = {
//todo create the body using the executed action in repository
val oaiFrame = createOaiFrame
val sets: Seq[ConfigObject] = repository.oaiConfig.sets.sets
//val configTuples: Seq[(ConfigValue, ConfigValue)] = sets.map(f => (f.get("spec"),f.get("name")))
val verbBody: RewriteRule = new RewriteRule {
override def transform(n: Node): Seq[Node] = n match {
case elem: Elem if elem.label == "request" =>
elem ++ {
val iterable: immutable.Iterable[Elem] =
for ((par,_) <- parameter.badArguments) yield
<error code="badArgument">{s"Illegal argument $par in request"}</error>
iterable.toSeq
}
case n => n
}
}
new RuleTransformer(verbBody).transform(oaiFrame)
}
}
/*
* generic OAI Server - agnostic in relation to the data repository
* initially created for memobase project
*
* Copyright (C) 2021 UB Basel
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program 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 Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*
*/
package org.swissbib.memobase.oai.response
import modules.{OAIContent, OaiRepository}
import org.swissbib.memobase.oai.common.validation.OaiParameterBase
import play.api.Configuration
import scala.xml.{Elem, Node, XML}
import scala.xml.transform.{RewriteRule, RuleTransformer}
case class GetRecordResponse(config: Configuration
,repository: OaiRepository
,result: OAIContent
,parameter: OaiParameterBase) extends OaiResponse(repository.oaiConfig
, parameter) {
override def toString: String = s"Ich bin eine GetRecord response mit Header für : GetRecord "
override def createResponse: Seq[Node] = {
//todo create the body using the executed action in repository
val oaiFrame = createOaiFrame
val verbBody: RewriteRule = new RewriteRule {
override def transform(n: Node): Seq[Node] = n match {
//its never empty because not found documents results in an error which is caught by Try - type
case elem: Elem if elem.label == "request" =>
elem ++
<GetRecord>
<record>
{makeHeader(identifier = result.docId) }
<metadata>
{XML.loadString(result.document)}
</metadata>
</record>
</GetRecord>
case n => n
}
}
new RuleTransformer(verbBody).transform(oaiFrame)
}
}
/*
* generic OAI Server - agnostic in relation to the data repository
* initially created for memobase project
*
* Copyright (C) 2021 UB Basel
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program 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 Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*
*/
package org.swissbib.memobase.oai.response
import modules.OaiRepository
import org.swissbib.memobase.oai.common.validation.OaiParameterBase
import play.api.Configuration
import scala.xml.{Elem, Node}
import scala.xml.transform.{RewriteRule, RuleTransformer}
case class IdentifyResponse(config: Configuration
,repository: OaiRepository
,parameter: OaiParameterBase) extends OaiResponse (repository.oaiConfig
,parameter) {
override def toString: String = s"Ich bin eine Identify response mit Header für : Identify "
override def createResponse: Seq[Node] = {
//Hinweise für xml transformation
//https://stackoverflow.com/questions/2199040/scala-xml-building-adding-children-to-existing-nodes
//https://stackoverflow.com/questions/7160298/scala-xml-parsing-constructingparser-splitting-text-content?rq=1
//https://github.com/scala/scala-xml/wiki/Getting-started
//https://github.com/lauris/awesome-scala#xml--html
val oaiFrame = createOaiFrame
val verbBody: RewriteRule = new RewriteRule {
override def transform(n: Node): Seq[Node] = n match {
case elem: Elem if elem.label == "request" =>
elem ++ <Identify>
<repositoryName>{repository.oaiConfig.identify.repositoryName}</repositoryName>
<baseURL>{repository.oaiConfig.identify.baseUrl}</baseURL>
<protocolVersion>{repository.oaiConfig.identify.protocolVersion}</protocolVersion>
<adminEmail>{repository.oaiConfig.identify.adminEmail}</adminEmail>
<earliestDatestamp>{repository.oaiConfig.identify.earliestDatestamp}</earliestDatestamp>
<deletedRecord>{repository.oaiConfig.identify.deletedRecord}</deletedRecord>
<granularity>{repository.oaiConfig.identify.granularity}</granularity>
</Identify>
case n => n
}
}
new RuleTransformer(verbBody).transform(oaiFrame)
}
}
/*
* generic OAI Server - agnostic in relation to the data repository
* initially created for memobase project
*
* Copyright (C) 2021 UB Basel
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program 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 Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*
*/
package org.swissbib.memobase.oai.response
import modules.OaiRepository
import org.swissbib.memobase.oai.common.validation.OaiParameterBase
import org.swissbib.memobase.oai.runner.ResultList
import play.api.Configuration
import java.time.Instant
import scala.xml.{Elem, Node}
import scala.xml.transform.{RewriteRule, RuleTransformer}
case class ListIdentifiersResponse( config: Configuration
,repository: OaiRepository
,resultList: ResultList
,parameter: OaiParameterBase) extends OaiResponse (repository.oaiConfig
,parameter) {
override def toString: String = s"Ich bin eine ListIdentifiers response mit Header für : ListIdentifiers"
override def createResponse: Seq[Node] = {
//todo create the body using the executed action in repository
val oaiFrame = createOaiFrame
val verbBody: RewriteRule = new RewriteRule {
override def transform(n: Node): Seq[Node] = n match {
case elem: Elem if elem.label == "request" =>
elem ++
<ListIdentifiers>
{
resultList.result.map(
node => {
{makeHeader(identifier = node.docId,
datestamp = Instant.parse(node.updateDate))}
}
)
}
{if (resultList.repositoryToken.isDefined) {
<resumptionToken>{resultList.repositoryToken}</resumptionToken>
}}
</ListIdentifiers>
case n => n
}
}
new RuleTransformer(verbBody).transform(oaiFrame)
}
}
/*
* generic OAI Server - agnostic in relation to the data repository
* initially created for memobase project
*
* Copyright (C) 2021 UB Basel
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program 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 Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*
*/
package org.swissbib.memobase.oai.response
import com.typesafe.config.ConfigObject
import modules.OaiRepository
import org.swissbib.memobase.oai.common.validation.OaiParameterBase
import play.api.Configuration
import scala.xml.{Elem, Node}
import scala.xml.transform.{RewriteRule, RuleTransformer}
case class ListMetadaFormatsResponse( config: Configuration
,repository: OaiRepository
,parameter: OaiParameterBase) extends OaiResponse (repository.oaiConfig
,parameter) {
override def toString: String = s"Ich bin eine ListMetadaFormats response mit Header für : ListMetadaFormats "
override def createResponse: Seq[Node] = {
//todo create the body using the executed action in repository
val oaiFrame = createOaiFrame
val sets: Seq[ConfigObject] = repository.oaiConfig.prefixes.prefixes
val configTuples = sets.map(f => (f.get("metadataPrefix"),
f.get("schema"),
f.get("metadataNamespace")))
val verbBody: RewriteRule = new RewriteRule {
override def transform(n: Node): Seq[Node] = n match {
case elem: Elem if elem.label == "request" =>
elem ++ <ListMetadataFormats>
{configTuples.map(tuple =>
<metadataFormat>
<metadataPrefix>{tuple._1.unwrapped()}</metadataPrefix>
<schema>{tuple._2.unwrapped()}</schema>
<metadataNamespace>{tuple._2.unwrapped()}</metadataNamespace>
</metadataFormat>
)}
</ListMetadataFormats>
case n => n
}
}
new RuleTransformer(verbBody).transform(oaiFrame)
}
}
/*
* generic OAI Server - agnostic in relation to the data repository
* initially created for memobase project
*
* Copyright (C) 2021 UB Basel
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program 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 Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*
*/
package org.swissbib.memobase.oai.response
import modules.OaiRepository
import org.swissbib.memobase.oai.common.validation.OaiParameterBase
import org.swissbib.memobase.oai.runner.ResultList
import play.api.Configuration
import java.time.Instant
import scala.xml.{Elem, Node, XML}
import scala.xml.transform.{RewriteRule, RuleTransformer}
case class ListRecordsResponse(config: Configuration
,repository: OaiRepository
,resultList: ResultList
,parameter: OaiParameterBase) extends OaiResponse (repository.oaiConfig
,parameter) {
override def toString: String = s"Ich bin eine ListRecords response mit Header für : ListRecords "
override def createResponse: Seq[Node] = {
//todo create the body using the executed action in repository
val oaiFrame = createOaiFrame
val verbBody: RewriteRule = new RewriteRule {
override def transform(n: Node): Seq[Node] = n match {
case elem: Elem if elem.label == "request" =>
elem ++
<ListRecords>
{
resultList.result.map(hit =>
<record>
{makeHeader(identifier = hit.docId,
datestamp = Instant.parse(hit.updateDate))}
<metadata>{XML.loadString(hit.document)}</metadata>
</record>)
}
{
/*
why doesn't this work??
runner.resultList.get.repositoryToken.map(
tokenvalue =>
(<resumptionToken>{tokenvalue}</resumptionToken>).get
)
*/
{if (resultList.repositoryToken.isDefined) {
<resumptionToken>{resultList.repositoryToken.get.token}</resumptionToken>
}}
}
</ListRecords>
case n => n
}
}
new RuleTransformer(verbBody).transform(oaiFrame)
}
}
/*
* generic OAI Server - agnostic in relation to the data repository
* initially created for memobase project
*
* Copyright (C) 2021 UB Basel
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program 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 Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*
*/
package org.swissbib.memobase.oai.response
import com.typesafe.config.{ConfigObject, ConfigValue}
import modules.OaiRepository
import org.swissbib.memobase.oai.common.validation.OaiParameterBase
import play.api.Configuration
import scala.xml.{Elem, Node}
import scala.xml.transform.{RewriteRule, RuleTransformer}
case class ListSetsResponse(config: Configuration
,repository: OaiRepository
,parameter: OaiParameterBase) extends OaiResponse (repository.oaiConfig
,parameter) {
override def toString: String = s"Ich bin eine ListSets response mit Header für : ListSets "
override def createResponse: Seq[Node] = {
//todo create the body using the executed action in repository
val oaiFrame = createOaiFrame
val sets: Seq[ConfigObject] = repository.oaiConfig.sets.sets
val configTuples: Seq[(ConfigValue, ConfigValue)] = sets.map(f => (f.get("spec"),f.get("name")))
val verbBody: RewriteRule = new RewriteRule {
override def transform(n: Node): Seq[Node] = n match {
case elem: Elem if elem.label == "request" =>
elem ++ <ListSets>
{configTuples.map(tuple =>
<set>
<setSpec>{tuple._1.unwrapped()}</setSpec>
<setName>{tuple._2.unwrapped()}</setName>
</set>
)}
</ListSets>
case n => n
}
}
new RuleTransformer(verbBody).transform(oaiFrame)
}
}
......@@ -24,19 +24,12 @@
package org.swissbib.memobase.oai.response
import java.time.Instant
import com.typesafe.config.{ConfigObject, ConfigValue}
import modules.{OAIContent, OaiRepository}
import org.swissbib.memobase.oai.common.util.OaiConfig
import org.swissbib.memobase.oai.common.validation.{BadArgumentsParameter, OaiParameterBase}
import org.swissbib.memobase.oai.runner.ResultList
import play.api.Configuration
import org.swissbib.memobase.oai.common.validation.OaiParameterBase
import scala.xml.{Elem, MetaData, Node, Null, Text, TopScope, UnprefixedAttribute}
import scala.collection.immutable
import scala.xml.transform.{RewriteRule, RuleTransformer}
import scala.xml.{Elem, MetaData, Node, Null, Text, TopScope, UnprefixedAttribute, XML}
sealed abstract class OaiResponse (oaiConfig: OaiConfig
abstract class OaiResponse (oaiConfig: OaiConfig
,parameter: OaiParameterBase) {
def makeHeader(del: Boolean = false,
......@@ -85,14 +78,6 @@ sealed abstract class OaiResponse (oaiConfig: OaiConfig
}
protected def createOaiFrame: Elem = {
/*
val oaiFrame =
<OAI-PMH xmlns="http://www.openarchives.org/OAI/2.0/" xsi:schemaLocation="http://www.openarchives.org/OAI/2.0/ http://www.openarchives.org/OAI/2.0/OAI-PMH.xsd">
<responseDate>{Instant.now()}</responseDate>
{createRequestTag}
</OAI-PMH>
*/
val oaiFrame =
//noinspection ScalaStyle
<OAI-PMH xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.openarchives.org/OAI/2.0/ http://www.openarchives.org/OAI/2.0/OAI-PMH.xsd" xmlns="http://www.openarchives.org/OAI/2.0/" >
......@@ -100,9 +85,7 @@ sealed abstract class OaiResponse (oaiConfig: OaiConfig
{createRequestTag}
</OAI-PMH>
oaiFrame
}
def createResponse:Seq[Node]
......@@ -111,274 +94,18 @@ sealed abstract class OaiResponse (oaiConfig: OaiConfig
def getVerb:String = ???
}
case class GetRecordResponse(config: Configuration
,repository: OaiRepository
,result: OAIContent
,parameter: OaiParameterBase) extends OaiResponse(repository.oaiConfig, parameter) {
override def toString: String = s"Ich bin eine GetRecord response mit Header für : GetRecord "
override def createResponse: Seq[Node] = {
//todo create the body using the executed action in repository
val oaiFrame = createOaiFrame
val verbBody: RewriteRule = new RewriteRule {
override def transform(n: Node): Seq[Node] = n match {
//its never empty because not found documents results in an error which is caught by Try - type
case elem: Elem if elem.label == "request" =>
elem ++
<GetRecord>