Skip to content

Commit

Permalink
Use types from the triplestore in predicate objects in ontologies (#767)
Browse files Browse the repository at this point in the history
* feature (webapi): Use LiteralV2 in PredicateInfoV2.

* refactor (webapi): Add OntologyLiteralV2, overlapping with LiteralV2.

* style (webapi): Fix missing and out-of-date copyright notices.

- Update release notes.

* docs (build): Update release notes.
  • Loading branch information
Benjamin Geer authored Mar 10, 2018
1 parent 2d7af4f commit 6a34e26
Show file tree
Hide file tree
Showing 21 changed files with 721 additions and 597 deletions.
3 changes: 3 additions & 0 deletions docs/rst/00-release-notes/v1.3.0.rst
Original file line number Diff line number Diff line change
Expand Up @@ -45,5 +45,8 @@ New features:
Bugfixes:
---------

- When API v2 served ``knora-api`` (default schema), ``salsah-gui:guiElement`` and ``salsah-gui:guiAttribute`` were not shown in properties in that ontology.
- The predicate ``salsah-gui:guiOrder`` was not accepted when creating a property via API v2.

.. _release: https://github.com/dhlab-basel/Knora/releases/tag/v1.3.0
.. _v1.3.0 milestone: https://github.com/dhlab-basel/Knora/milestone/7
Original file line number Diff line number Diff line change
Expand Up @@ -732,6 +732,11 @@ object OntologyConstants {
val GuiElementProp: IRI = SalsahGuiPrefixExpansion + "guiElement"
val GuiAttributeDefinition: IRI = SalsahGuiPrefixExpansion + "guiAttributeDefinition"
val GuiElementClass: IRI = SalsahGuiPrefixExpansion + "Guielement"

val Geometry: IRI = SalsahGuiPrefixExpansion + "Geometry"
val Colorpicker: IRI = SalsahGuiPrefixExpansion + "Colorpicker"
val Fileupload: IRI = SalsahGuiPrefixExpansion + "Fileupload"
val Richtext: IRI = SalsahGuiPrefixExpansion + "Richtext"
}

object KnoraApiV2Simple {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,8 @@ package org.knora.webapi.messages.store.triplestoremessages
import java.time.Instant

import akka.http.scaladsl.marshallers.sprayjson.SprayJsonSupport
import org.knora.webapi.util.ErrorHandlingMap
import org.knora.webapi.{IRI, InconsistentTriplestoreDataException, TriplestoreResponseException}
import org.knora.webapi.util.{ErrorHandlingMap, SmartIri}
import org.knora.webapi.{IRI, InconsistentTriplestoreDataException, OntologySchema, TriplestoreResponseException}
import spray.json.{DefaultJsonProtocol, DeserializationException, JsObject, JsString, JsValue, JsonFormat, NullOptions, RootJsonFormat, _}

//////////////////////////////////////////////////////////////////////////////////////////////////////////////////
Expand Down Expand Up @@ -257,14 +257,30 @@ case class BlankNodeSubjectV2(value: String) extends SubjectV2 {
sealed trait LiteralV2

/**
* Represents an object IRI.
* Represents a literal read from an ontology in the triplestore.
*/
sealed trait OntologyLiteralV2

/**
* Represents an IRI literal.
*
* @param value the IRI.
*/
case class IriLiteralV2(value: IRI) extends LiteralV2 {
override def toString: IRI = value
}

/**
* Represents an IRI literal as a [[SmartIri]].
* @param value the IRI.
*/
case class SmartIriLiteralV2(value: SmartIri) extends OntologyLiteralV2 {
override def toString: IRI = value.toString

def toOntologySchema(targetSchema: OntologySchema) = SmartIriLiteralV2(value.toOntologySchema(targetSchema))
}

/**
* Represents a blank node identifier.
*
Expand All @@ -280,7 +296,7 @@ case class BlankNodeLiteralV2(value: String) extends LiteralV2 {
* @param value the string value.
* @param language the optional language tag.
*/
case class StringLiteralV2(value: String, language: Option[String] = None) extends LiteralV2 with Ordered[StringLiteralV2] {
case class StringLiteralV2(value: String, language: Option[String] = None) extends LiteralV2 with OntologyLiteralV2 with Ordered[StringLiteralV2] {
override def toString: String = value

def compare(that: StringLiteralV2): Int = this.value.compareTo(that.value)
Expand All @@ -291,7 +307,7 @@ case class StringLiteralV2(value: String, language: Option[String] = None) exten
*
* @param value the boolean value.
*/
case class BooleanLiteralV2(value: Boolean) extends LiteralV2 {
case class BooleanLiteralV2(value: Boolean) extends LiteralV2 with OntologyLiteralV2 {
override def toString: String = value.toString
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ package org.knora.webapi.messages.v1.responder.ontologymessages

import akka.http.scaladsl.marshallers.sprayjson.SprayJsonSupport
import org.knora.webapi._
import org.knora.webapi.messages.store.triplestoremessages.StringLiteralV2
import org.knora.webapi.messages.v1.responder.standoffmessages.StandoffDataTypeClasses
import org.knora.webapi.messages.v1.responder.usermessages.UserProfileV1
import org.knora.webapi.messages.v1.responder.{KnoraRequestV1, KnoraResponseV1}
Expand Down Expand Up @@ -279,12 +280,17 @@ class PredicateInfoV1(predicateInfoV2: PredicateInfoV2) {
/**
* Returns the objects of the predicate that have no language codes.
*/
def objects: Set[String] = predicateInfoV2.objects
def objects: Set[String] = predicateInfoV2.objects.filter {
case StringLiteralV2(_, Some(_)) => false
case _ => true
}.map(_.toString).toSet

/**
* Returns the objects of the predicate that have language codes: a Map of language codes to literals.
*/
def objectsWithLang: Map[String, String] = predicateInfoV2.objectsWithLang
def objectsWithLang: Map[String, String] = predicateInfoV2.objects.collect {
case StringLiteralV2(str, Some(lang)) => lang -> str
}.toMap
}

/**
Expand All @@ -298,7 +304,7 @@ sealed trait EntityInfoV1 {
/**
* Returns a [[Map]] of predicate IRIs to [[PredicateInfoV1]] objects.
*/
def predicates: Map[IRI, PredicateInfoV1] = {
lazy val predicates: Map[IRI, PredicateInfoV1] = {
entityInfoContent.predicates.map {
case (smartIri, predicateInfoV2) => smartIri.toString -> new PredicateInfoV1(predicateInfoV2)
}
Expand All @@ -314,20 +320,23 @@ sealed trait EntityInfoV1 {
* if the predicate has no objects.
*/
def getPredicateObject(predicateIri: IRI, preferredLangs: Option[(String, String)] = None): Option[String] = {
entityInfoContent.getPredicateLiteralObject(
entityInfoContent.getPredicateStringLiteralObject(
predicateIri = predicateIri.toSmartIri,
preferredLangs = preferredLangs
)
) match {
case Some(obj) => Some(obj)
case None => predicates.get(predicateIri).flatMap(_.objects.headOption)
}
}

/**
* Returns all the objects specified for a given predicate.
* Returns all the string (non-IRI) objects specified without language tags for a given predicate.
*
* @param predicateIri the IRI of the predicate.
* @return the predicate's objects, or an empty set if this entity doesn't have the specified predicate.
*/
def getPredicateObjectsWithoutLang(predicateIri: IRI): Set[String] = {
entityInfoContent.getPredicateLiteralsWithoutLang(predicateIri.toSmartIri)
def getPredicateStringObjectsWithoutLang(predicateIri: IRI): Set[String] = {
entityInfoContent.getPredicateStringLiteralObjectsWithoutLang(predicateIri.toSmartIri).toSet
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
package org.knora.webapi.messages.v2.responder.ontologymessages

import org.knora.webapi._
import org.knora.webapi.messages.store.triplestoremessages.{OntologyLiteralV2, SmartIriLiteralV2, StringLiteralV2}
import org.knora.webapi.messages.v2.responder.ontologymessages.Cardinality.KnoraCardinalityInfo
import org.knora.webapi.util.IriConversions._
import org.knora.webapi.util.{SmartIri, StringFormatter}
Expand Down Expand Up @@ -1134,12 +1135,13 @@ object KnoraApiV2Simple {
* @return a [[PredicateInfoV2]].
*/
private def makePredicate(predicateIri: IRI,
objects: Set[String] = Set.empty[String],
objects: Seq[OntologyLiteralV2] = Seq.empty[OntologyLiteralV2],
objectsWithLang: Map[String, String] = Map.empty[String, String]): PredicateInfoV2 = {
PredicateInfoV2(
predicateIri = predicateIri.toSmartIri,
objects = objects,
objectsWithLang = objectsWithLang
objects = objects ++ objectsWithLang.map {
case (lang, str) => StringLiteralV2(str, Some(lang))
}
)
}

Expand All @@ -1162,22 +1164,22 @@ object KnoraApiV2Simple {
objectType: Option[IRI] = None): ReadPropertyInfoV2 = {
val propTypePred = makePredicate(
predicateIri = OntologyConstants.Rdf.Type,
objects = Set(propertyType)
objects = Seq(SmartIriLiteralV2(propertyType.toSmartIri))
)

val maybeSubjectTypePred = subjectType.map {
subjType =>
makePredicate(
predicateIri = OntologyConstants.KnoraApiV2Simple.SubjectType,
objects = Set(subjType)
objects = Seq(SmartIriLiteralV2(subjType.toSmartIri))
)
}

val maybeObjectTypePred = objectType.map {
objType =>
makePredicate(
predicateIri = OntologyConstants.KnoraApiV2Simple.ObjectType,
objects = Set(objType)
objects = Seq(SmartIriLiteralV2(objType.toSmartIri))
)
}

Expand Down Expand Up @@ -1213,7 +1215,7 @@ object KnoraApiV2Simple {

val rdfType = OntologyConstants.Rdf.Type.toSmartIri -> PredicateInfoV2(
predicateIri = OntologyConstants.Rdf.Type.toSmartIri,
objects = Set(OntologyConstants.Owl.Class)
objects = Seq(SmartIriLiteralV2(OntologyConstants.Owl.Class.toSmartIri))
)

ReadClassInfoV2(
Expand Down Expand Up @@ -1250,7 +1252,7 @@ object KnoraApiV2Simple {

val rdfType = OntologyConstants.Rdf.Type.toSmartIri -> PredicateInfoV2(
predicateIri = OntologyConstants.Rdf.Type.toSmartIri,
objects = Set(OntologyConstants.Rdfs.Datatype)
objects = Seq(SmartIriLiteralV2(OntologyConstants.Rdfs.Datatype.toSmartIri))
)

ReadClassInfoV2(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
package org.knora.webapi.messages.v2.responder.ontologymessages

import org.knora.webapi._
import org.knora.webapi.messages.store.triplestoremessages.{OntologyLiteralV2, SmartIriLiteralV2, StringLiteralV2}
import org.knora.webapi.messages.v2.responder.ontologymessages.Cardinality.KnoraCardinalityInfo
import org.knora.webapi.util.IriConversions._
import org.knora.webapi.util.{SmartIri, StringFormatter}
Expand Down Expand Up @@ -946,12 +947,12 @@ object KnoraApiV2WithValueObjects {
isEditable = true,
predicates = Seq(
makePredicate(
predicateIri = OntologyConstants.SalsahGui.GuiElementProp,
objects = Set(OntologyConstants.SalsahGui.Colorpicker)
predicateIri = OntologyConstants.SalsahGuiApiV2WithValueObjects.GuiElementProp,
objects = Seq(SmartIriLiteralV2(OntologyConstants.SalsahGuiApiV2WithValueObjects.Colorpicker.toSmartIri))
),
makePredicate(
predicateIri = OntologyConstants.SalsahGui.GuiAttribute,
objects = Set("ncolors=8")
predicateIri = OntologyConstants.SalsahGuiApiV2WithValueObjects.GuiAttribute,
objects = Seq(StringLiteralV2("ncolors=8"))
),
makePredicate(
predicateIri = OntologyConstants.Rdfs.Label,
Expand Down Expand Up @@ -981,12 +982,12 @@ object KnoraApiV2WithValueObjects {
isEditable = true,
predicates = Seq(
makePredicate(
predicateIri = OntologyConstants.SalsahGui.GuiElementProp,
objects = Set(OntologyConstants.SalsahGui.Geometry)
predicateIri = OntologyConstants.SalsahGuiApiV2WithValueObjects.GuiElementProp,
objects = Seq(SmartIriLiteralV2(OntologyConstants.SalsahGuiApiV2WithValueObjects.Geometry.toSmartIri))
),
makePredicate(
predicateIri = OntologyConstants.SalsahGui.GuiAttribute,
objects = Set("width=95%;rows=4;wrap=soft")
predicateIri = OntologyConstants.SalsahGuiApiV2WithValueObjects.GuiAttribute,
objects = Seq(StringLiteralV2("width=95%;rows=4;wrap=soft"))
),
makePredicate(
predicateIri = OntologyConstants.Rdfs.Label,
Expand Down Expand Up @@ -1016,8 +1017,8 @@ object KnoraApiV2WithValueObjects {
isEditable = true,
predicates = Seq(
makePredicate(
predicateIri = OntologyConstants.SalsahGui.GuiElementProp,
objects = Set(OntologyConstants.SalsahGui.Richtext)
predicateIri = OntologyConstants.SalsahGuiApiV2WithValueObjects.GuiElementProp,
objects = Seq(SmartIriLiteralV2(OntologyConstants.SalsahGuiApiV2WithValueObjects.Richtext.toSmartIri))
),
makePredicate(
predicateIri = OntologyConstants.Rdfs.Label,
Expand Down Expand Up @@ -1046,8 +1047,8 @@ object KnoraApiV2WithValueObjects {
subPropertyOf = Set(OntologyConstants.KnoraApiV2WithValueObjects.HasValue),
predicates = Seq(
makePredicate(
predicateIri = OntologyConstants.SalsahGui.GuiElementProp,
objects = Set(OntologyConstants.SalsahGui.Fileupload)
predicateIri = OntologyConstants.SalsahGuiApiV2WithValueObjects.GuiElementProp,
objects = Seq(SmartIriLiteralV2(OntologyConstants.SalsahGuiApiV2WithValueObjects.Fileupload.toSmartIri))
),
makePredicate(
predicateIri = OntologyConstants.Rdfs.Label,
Expand Down Expand Up @@ -1077,8 +1078,8 @@ object KnoraApiV2WithValueObjects {
isEditable = true,
predicates = Seq(
makePredicate(
predicateIri = OntologyConstants.SalsahGui.GuiElementProp,
objects = Set(OntologyConstants.SalsahGui.Fileupload)
predicateIri = OntologyConstants.SalsahGuiApiV2WithValueObjects.GuiElementProp,
objects = Seq(SmartIriLiteralV2(OntologyConstants.SalsahGuiApiV2WithValueObjects.Fileupload.toSmartIri))
),
makePredicate(
predicateIri = OntologyConstants.Rdfs.Label,
Expand Down Expand Up @@ -1108,8 +1109,8 @@ object KnoraApiV2WithValueObjects {
isEditable = true,
predicates = Seq(
makePredicate(
predicateIri = OntologyConstants.SalsahGui.GuiElementProp,
objects = Set(OntologyConstants.SalsahGui.Fileupload)
predicateIri = OntologyConstants.SalsahGuiApiV2WithValueObjects.GuiElementProp,
objects = Seq(SmartIriLiteralV2(OntologyConstants.SalsahGuiApiV2WithValueObjects.Fileupload.toSmartIri))
),
makePredicate(
predicateIri = OntologyConstants.Rdfs.Label,
Expand Down Expand Up @@ -1139,8 +1140,8 @@ object KnoraApiV2WithValueObjects {
isEditable = true,
predicates = Seq(
makePredicate(
predicateIri = OntologyConstants.SalsahGui.GuiElementProp,
objects = Set(OntologyConstants.SalsahGui.Fileupload)
predicateIri = OntologyConstants.SalsahGuiApiV2WithValueObjects.GuiElementProp,
objects = Seq(SmartIriLiteralV2(OntologyConstants.SalsahGuiApiV2WithValueObjects.Fileupload.toSmartIri))
),
makePredicate(
predicateIri = OntologyConstants.Rdfs.Label,
Expand Down Expand Up @@ -1170,8 +1171,8 @@ object KnoraApiV2WithValueObjects {
isEditable = true,
predicates = Seq(
makePredicate(
predicateIri = OntologyConstants.SalsahGui.GuiElementProp,
objects = Set(OntologyConstants.SalsahGui.Fileupload)
predicateIri = OntologyConstants.SalsahGuiApiV2WithValueObjects.GuiElementProp,
objects = Seq(SmartIriLiteralV2(OntologyConstants.SalsahGuiApiV2WithValueObjects.Fileupload.toSmartIri))
),
makePredicate(
predicateIri = OntologyConstants.Rdfs.Label,
Expand Down Expand Up @@ -1201,8 +1202,8 @@ object KnoraApiV2WithValueObjects {
isEditable = true,
predicates = Seq(
makePredicate(
predicateIri = OntologyConstants.SalsahGui.GuiElementProp,
objects = Set(OntologyConstants.SalsahGui.Fileupload)
predicateIri = OntologyConstants.SalsahGuiApiV2WithValueObjects.GuiElementProp,
objects = Seq(SmartIriLiteralV2(OntologyConstants.SalsahGuiApiV2WithValueObjects.Fileupload.toSmartIri))
),
makePredicate(
predicateIri = OntologyConstants.Rdfs.Label,
Expand Down Expand Up @@ -1232,8 +1233,8 @@ object KnoraApiV2WithValueObjects {
isEditable = true,
predicates = Seq(
makePredicate(
predicateIri = OntologyConstants.SalsahGui.GuiElementProp,
objects = Set(OntologyConstants.SalsahGui.Fileupload)
predicateIri = OntologyConstants.SalsahGuiApiV2WithValueObjects.GuiElementProp,
objects = Seq(SmartIriLiteralV2(OntologyConstants.SalsahGuiApiV2WithValueObjects.Fileupload.toSmartIri))
),
makePredicate(
predicateIri = OntologyConstants.Rdfs.Label,
Expand Down Expand Up @@ -2670,12 +2671,13 @@ object KnoraApiV2WithValueObjects {
* @return a [[PredicateInfoV2]].
*/
private def makePredicate(predicateIri: IRI,
objects: Set[String] = Set.empty[String],
objects: Seq[OntologyLiteralV2] = Seq.empty[OntologyLiteralV2],
objectsWithLang: Map[String, String] = Map.empty[String, String]): PredicateInfoV2 = {
PredicateInfoV2(
predicateIri = predicateIri.toSmartIri,
objects = objects,
objectsWithLang = objectsWithLang
objects = objects ++ objectsWithLang.map {
case (lang, str) => StringLiteralV2(str, Some(lang))
}
)
}

Expand Down Expand Up @@ -2705,22 +2707,22 @@ object KnoraApiV2WithValueObjects {
objectType: Option[IRI] = None): ReadPropertyInfoV2 = {
val propTypePred = makePredicate(
predicateIri = OntologyConstants.Rdf.Type,
objects = Set(propertyType)
objects = Seq(SmartIriLiteralV2(propertyType.toSmartIri))
)

val maybeSubjectTypePred = subjectType.map {
subjType =>
makePredicate(
predicateIri = OntologyConstants.KnoraApiV2WithValueObjects.SubjectType,
objects = Set(subjType)
objects = Seq(SmartIriLiteralV2(subjType.toSmartIri))
)
}

val maybeObjectTypePred = objectType.map {
objType =>
makePredicate(
predicateIri = OntologyConstants.KnoraApiV2WithValueObjects.ObjectType,
objects = Set(objType)
objects = Seq(SmartIriLiteralV2(objType.toSmartIri))
)
}

Expand Down Expand Up @@ -2764,7 +2766,7 @@ object KnoraApiV2WithValueObjects {
inheritedCardinalities: Map[SmartIri, KnoraCardinalityInfo] = Map.empty[SmartIri, KnoraCardinalityInfo]): ReadClassInfoV2 = {
val rdfType = OntologyConstants.Rdf.Type.toSmartIri -> PredicateInfoV2(
predicateIri = OntologyConstants.Rdf.Type.toSmartIri,
objects = Set(OntologyConstants.Owl.Class)
objects = Seq(SmartIriLiteralV2(OntologyConstants.Owl.Class.toSmartIri))
)

ReadClassInfoV2(
Expand Down
Loading

0 comments on commit 6a34e26

Please sign in to comment.