Skip to content

Commit

Permalink
fix (webapi): Fix #885.
Browse files Browse the repository at this point in the history
  • Loading branch information
Benjamin Geer committed Jun 13, 2018
1 parent 8b481e1 commit a6527cf
Show file tree
Hide file tree
Showing 2 changed files with 55 additions and 9 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -340,7 +340,7 @@ object CreatePropertyRequestV2 extends KnoraJsonLDRequestReaderV2[CreateProperty
}
}

val objectType = propertyInfoContent.requireIriPredicate(OntologyConstants.KnoraApiV2WithValueObjects.ObjectType.toSmartIri, throw BadRequestException(s"Missing knora-api:objectType"))
val objectType = propertyInfoContent.requireIriObject(OntologyConstants.KnoraApiV2WithValueObjects.ObjectType.toSmartIri, throw BadRequestException(s"Missing knora-api:objectType"))

if (!(objectType.isKnoraApiV2EntityIri && objectType.getOntologySchema.contains(ApiV2WithValueObjects))) {
throw BadRequestException(s"Invalid knora-api:objectType: $objectType")
Expand Down Expand Up @@ -1323,6 +1323,24 @@ case class PredicateInfoV2(predicateIri: SmartIri,
}
}

/**
* Requires this predicate to have at least one IRI, and returns those objects.
*
* @param errorFun a function that throws an error. It will be called if the predicate has no objects,
* or has non-IRI objects.
* @return the predicate's IRI objects.
*/
def requireIriObjects(errorFun: => Nothing): Set[SmartIri] = {
if (objects.isEmpty) {
errorFun
}

objects.map {
case SmartIriLiteralV2(iri) => iri
case _ => errorFun
}.toSet
}

/**
* Undoes the SPARQL-escaping of predicate objects. This method is meant to be used after an update, when the
* input (whose predicate objects have been escaped for use in SPARQL) needs to be compared with the updated data
Expand Down Expand Up @@ -1498,10 +1516,22 @@ sealed trait EntityInfoContentV2 {
* @param errorFun a function that will be called if the predicate is absent or if its object is not an IRI.
* @return a [[SmartIri]] representing the predicate's object.
*/
def requireIriPredicate(predicateIri: SmartIri, errorFun: => Nothing): SmartIri = {
def requireIriObject(predicateIri: SmartIri, errorFun: => Nothing): SmartIri = {
predicates.getOrElse(predicateIri, errorFun).requireIriObject(errorFun)
}

/**
* Checks that a predicate is present in this [[EntityInfoContentV2]] and that it at least one IRI object, and
* returns those objects as a set of [[SmartIri]] instances.
*
* @param predicateIri the IRI of the predicate.
* @param errorFun a function that will be called if the predicate is absent or if its objects are not IRIs.
* @return a set of [[SmartIri]] instances representing the predicate's objects.
*/
def requireIriObjects(predicateIri: SmartIri, errorFun: => Nothing): Set[SmartIri] = {
predicates.getOrElse(predicateIri, errorFun).requireIriObjects(errorFun)
}

/**
* A convenience method that returns the `rdf:type` of this entity. Throws [[InconsistentTriplestoreDataException]]
* if the entity's predicates do not include `rdf:type`.
Expand Down Expand Up @@ -2286,7 +2316,15 @@ case class ClassInfoContentV2(classIri: SmartIri,
}

override def getRdfType: SmartIri = {
requireIriPredicate(OntologyConstants.Rdf.Type.toSmartIri, throw InconsistentTriplestoreDataException(s"Class $classIri has no rdf:type"))
val classTypeSet: Set[SmartIri] = requireIriObjects(OntologyConstants.Rdf.Type.toSmartIri, throw InconsistentTriplestoreDataException(s"The rdf:type of $classIri is missing or invalid")).filter {
classType => OntologyConstants.ClassTypes.contains(classType.toString)
}

if (classTypeSet.size == 1) {
classTypeSet.head
} else {
throw InconsistentTriplestoreDataException(s"The rdf:type of $classIri is invalid")
}
}

/**
Expand Down Expand Up @@ -2515,7 +2553,15 @@ case class PropertyInfoContentV2(propertyIri: SmartIri,
}

override def getRdfType: SmartIri = {
requireIriPredicate(OntologyConstants.Rdf.Type.toSmartIri, throw InconsistentTriplestoreDataException(s"Property $propertyIri has no rdf:type"))
val propertyTypeSet: Set[SmartIri] = requireIriObjects(OntologyConstants.Rdf.Type.toSmartIri, throw InconsistentTriplestoreDataException(s"The rdf:type of $propertyIri is missing or invalid")).filter {
classType => OntologyConstants.PropertyTypes.contains(classType.toString)
}

if (propertyTypeSet.size == 1) {
propertyTypeSet.head
} else {
throw InconsistentTriplestoreDataException(s"The rdf:type of $propertyIri is invalid")
}
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1515,7 +1515,7 @@ class OntologyResponderV2 extends Responder {

// Check that the class's rdf:type is owl:Class.

rdfType: SmartIri = internalClassDef.requireIriPredicate(OntologyConstants.Rdf.Type.toSmartIri, throw BadRequestException(s"No rdf:type specified"))
rdfType: SmartIri = internalClassDef.requireIriObject(OntologyConstants.Rdf.Type.toSmartIri, throw BadRequestException(s"No rdf:type specified"))

_ = if (rdfType != OntologyConstants.Owl.Class.toSmartIri) {
throw BadRequestException(s"Invalid rdf:type for property: $rdfType")
Expand Down Expand Up @@ -1800,7 +1800,7 @@ class OntologyResponderV2 extends Responder {

// Check that the class's rdf:type is owl:Class.

rdfType: SmartIri = internalClassDef.requireIriPredicate(OntologyConstants.Rdf.Type.toSmartIri, throw BadRequestException(s"No rdf:type specified"))
rdfType: SmartIri = internalClassDef.requireIriObject(OntologyConstants.Rdf.Type.toSmartIri, throw BadRequestException(s"No rdf:type specified"))

_ = if (rdfType != OntologyConstants.Owl.Class.toSmartIri) {
throw BadRequestException(s"Invalid rdf:type for property: $rdfType")
Expand Down Expand Up @@ -1976,7 +1976,7 @@ class OntologyResponderV2 extends Responder {

// Check that the class's rdf:type is owl:Class.

rdfType: SmartIri = internalClassDef.requireIriPredicate(OntologyConstants.Rdf.Type.toSmartIri, throw BadRequestException(s"No rdf:type specified"))
rdfType: SmartIri = internalClassDef.requireIriObject(OntologyConstants.Rdf.Type.toSmartIri, throw BadRequestException(s"No rdf:type specified"))

_ = if (rdfType != OntologyConstants.Owl.Class.toSmartIri) {
throw BadRequestException(s"Invalid rdf:type for property: $rdfType")
Expand Down Expand Up @@ -2415,7 +2415,7 @@ class OntologyResponderV2 extends Responder {

// Check that the property's rdf:type is owl:ObjectProperty.

rdfType: SmartIri = internalPropertyDef.requireIriPredicate(OntologyConstants.Rdf.Type.toSmartIri, throw BadRequestException(s"No rdf:type specified"))
rdfType: SmartIri = internalPropertyDef.requireIriObject(OntologyConstants.Rdf.Type.toSmartIri, throw BadRequestException(s"No rdf:type specified"))

_ = if (rdfType != OntologyConstants.Owl.ObjectProperty.toSmartIri) {
throw BadRequestException(s"Invalid rdf:type for property: $rdfType")
Expand Down Expand Up @@ -2516,7 +2516,7 @@ class OntologyResponderV2 extends Responder {

// Check that the object class constraint designates an appropriate class that exists.

objectClassConstraint: SmartIri = internalPropertyDef.requireIriPredicate(OntologyConstants.KnoraBase.ObjectClassConstraint.toSmartIri, throw BadRequestException(s"No knora-api:objectType specified"))
objectClassConstraint: SmartIri = internalPropertyDef.requireIriObject(OntologyConstants.KnoraBase.ObjectClassConstraint.toSmartIri, throw BadRequestException(s"No knora-api:objectType specified"))

// If this is a value property, ensure its object class constraint is not LinkValue or a file value class.
_ = if (!isLinkProp) {
Expand Down

0 comments on commit a6527cf

Please sign in to comment.