.
This commit is contained in:
+16
-29
@@ -20,6 +20,7 @@ use oxigraph::model::vocab::{rdf, rdfs};
|
||||
use oxigraph::model::{BaseDirection, Dataset, NamedNode, NamedNodeRef, Quad, Term};
|
||||
use tracing::{debug, debug_span, error, trace};
|
||||
use crate::rdf::language;
|
||||
use crate::rdf::vocab::rda;
|
||||
use crate::widget::iri_input::iri_input;
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
@@ -314,7 +315,7 @@ impl Publisher {
|
||||
if let Some(search_state) = &mut self.search_state {
|
||||
search_state.action = action;
|
||||
} else {
|
||||
if let Some(entity) = self.ontology.labeled_entities(&*language::ENGLISH_OR_UNTAGGED).next() {
|
||||
if let Some(entity) = self.ontology.searchable_classes(&*language::ENGLISH_OR_UNTAGGED).next() {
|
||||
let (id, window_task) = window::open(Settings::default());
|
||||
self.search_state = Some(SearchState {
|
||||
window_id: id,
|
||||
@@ -450,7 +451,7 @@ impl Publisher {
|
||||
Message::SaveGraph(overwrite) => {
|
||||
let client = self.http_client.clone();
|
||||
let options = SerializationOptions::from_format(RdfFormat::Turtle)
|
||||
;//.with_filter(self.ontology.exclude_read_only());
|
||||
.with_filter(self.ontology.exclude_read_only());
|
||||
let request = self
|
||||
.document
|
||||
.to_update(options)
|
||||
@@ -540,21 +541,9 @@ impl Publisher {
|
||||
container(space()).width(BUTTON_WIDTH)
|
||||
};
|
||||
|
||||
let property_label = self
|
||||
.ontology
|
||||
.info(&triple.predicate, &*language::ENGLISH_OR_UNTAGGED)
|
||||
.label;
|
||||
|
||||
let property: Element<Message> = if state.read_only {
|
||||
text(property_label).into()
|
||||
} else {
|
||||
button(text(property_label))
|
||||
.on_press(Message::OpenQueryWindow(
|
||||
SearchResultClickAction::Predicate(key),
|
||||
))
|
||||
.style(button::text)
|
||||
.into()
|
||||
};
|
||||
let predicate_input = iri_input(self.ontology.prefixes(), "Predicate", triple.predicate.as_str())
|
||||
.on_input(move |value| Message::ValueUpdated(key, value))
|
||||
.on_control_click(Message::OpenQueryWindow(SearchResultClickAction::Predicate(key)));
|
||||
|
||||
let term = TermHelper::new(&triple.object);
|
||||
|
||||
@@ -630,7 +619,7 @@ impl Publisher {
|
||||
|
||||
let row = row![
|
||||
button_area,
|
||||
property,
|
||||
predicate_input,
|
||||
value_label,
|
||||
object_input,
|
||||
datatype_selector,
|
||||
@@ -646,15 +635,12 @@ impl Publisher {
|
||||
|
||||
fn view_new_entity_buttons(
|
||||
&self,
|
||||
entities: impl Iterator<Item = NamedNode>,
|
||||
entities: impl IntoIterator<Item = LabeledIri>,
|
||||
) -> Element<'_, Message> {
|
||||
let buttons = entities.map(|entity| {
|
||||
let label = self
|
||||
.ontology
|
||||
.info(&entity, &*language::ENGLISH_OR_UNTAGGED)
|
||||
.label;
|
||||
let buttons = entities.into_iter().map(|entity| {
|
||||
let label = format!("{} ({})", entity.label, self.ontology.abbreviate(entity.iri.as_ref()));
|
||||
button(text(label))
|
||||
.on_press(Message::NewDocument(entity))
|
||||
.on_press(Message::NewDocument(entity.iri))
|
||||
.into()
|
||||
});
|
||||
|
||||
@@ -671,7 +657,7 @@ impl Publisher {
|
||||
text_input("Query", &search_state.query).on_input(Message::QueryUpdated);
|
||||
|
||||
let mut entities = self.ontology
|
||||
.labeled_entities(&*language::ENGLISH_OR_UNTAGGED)
|
||||
.searchable_classes(&*language::ENGLISH_OR_UNTAGGED)
|
||||
.collect::<Vec<_>>();
|
||||
entities.sort_by(|a, b| Ord::cmp(&a.label, &b.label));
|
||||
|
||||
@@ -743,11 +729,12 @@ impl Publisher {
|
||||
.collect();
|
||||
|
||||
let body: Element<Message> = if self.show_new_document_buttons {
|
||||
let subclasses = self.ontology.subclasses_of(&rda::ENTITY.into_owned());
|
||||
let labeled_subclasses = subclasses.iter().map(|iri| self.ontology.info(iri, &*language::ENGLISH_OR_UNTAGGED));
|
||||
column![
|
||||
//self.view_new_entity_buttons(self.ontology.subclass_of(gl::ENTITY)),
|
||||
//self.view_new_entity_buttons(self.ontology.subclass_of(rda::ENTITY)),
|
||||
]
|
||||
.into()
|
||||
self.view_new_entity_buttons(labeled_subclasses),
|
||||
].into()
|
||||
} else {
|
||||
column(rows).into()
|
||||
};
|
||||
|
||||
@@ -13,6 +13,14 @@ pub fn term_to_named_node(term: &Term) -> Option<&NamedNode> {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn term_into_named_node(term: Term) -> Option<NamedNode> {
|
||||
if let Term::NamedNode(node) = term {
|
||||
Some(node)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
pub fn term_into_string(term: Term) -> Option<String> {
|
||||
term_as_str(&term).map(String::from)
|
||||
}
|
||||
@@ -30,18 +38,6 @@ pub fn term_as_str(term: &Term) -> Option<&str> {
|
||||
}
|
||||
}
|
||||
|
||||
/*pub fn term_to_tagged_string(term: &Term) -> Option<(String, Option<LanguageTag<String>>)> {
|
||||
term_as_str(&term).and_then(|value| {
|
||||
if let Term::Literal(literal) = term {
|
||||
literal.language()
|
||||
.map(|language| {
|
||||
let tag = LanguageTag::parse(language.to_string()).ok();
|
||||
(value.to_string(), tag)
|
||||
})
|
||||
} else { None }
|
||||
})
|
||||
}*/
|
||||
|
||||
pub fn term_to_boolean(term: &Term) -> Option<bool> {
|
||||
if let Term::Literal(literal) = term {
|
||||
if literal.datatype() == xsd::BOOLEAN {
|
||||
|
||||
@@ -1,302 +0,0 @@
|
||||
@prefix : <https://graphofliberty.org/2026/04/ont/> .
|
||||
@prefix ldp: <http://www.w3.org/ns/ldp#> .
|
||||
@prefix owl: <http://www.w3.org/2002/07/owl#> .
|
||||
@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
|
||||
@prefix xml: <http://www.w3.org/XML/1998/namespace> .
|
||||
@prefix xsd: <http://www.w3.org/2001/XMLSchema#> .
|
||||
@prefix rdaa: <http://rdaregistry.info/Elements/a/> .
|
||||
@prefix rdac: <http://rdaregistry.info/Elements/c/> .
|
||||
@prefix rdae: <http://rdaregistry.info/Elements/e/> .
|
||||
@prefix rdai: <http://rdaregistry.info/Elements/i/> .
|
||||
@prefix rdam: <http://rdaregistry.info/Elements/m/> .
|
||||
@prefix rdan: <http://rdaregistry.info/Elements/n/> .
|
||||
@prefix rdap: <http://rdaregistry.info/Elements/p/> .
|
||||
@prefix rdat: <http://rdaregistry.info/Elements/t/> .
|
||||
@prefix rdaw: <http://rdaregistry.info/Elements/w/> .
|
||||
@prefix rdax: <http://rdaregistry.info/Elements/x/> .
|
||||
@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
|
||||
@prefix skos: <http://www.w3.org/2004/02/skos/core#> .
|
||||
@prefix fedora: <http://fedora.info/definitions/v4/repository#> .
|
||||
@base <https://graphofliberty.org/2026/04/ont/> .
|
||||
|
||||
<https://graphofliberty.org/2026/04/ont> rdf:type owl:Ontology .
|
||||
|
||||
#################################################################
|
||||
# Annotation properties
|
||||
#################################################################
|
||||
|
||||
### http://www.w3.org/2000/01/rdf-schema#value
|
||||
rdfs:value rdf:type owl:AnnotationProperty .
|
||||
|
||||
|
||||
#################################################################
|
||||
# Datatypes
|
||||
#################################################################
|
||||
|
||||
### http://www.w3.org/1999/02/22-rdf-syntax-ns#dirLangString
|
||||
rdf:dirLangString rdf:type rdfs:Datatype ;
|
||||
rdfs:label "Directional language-tagged string"@en .
|
||||
|
||||
|
||||
### http://www.w3.org/1999/02/22-rdf-syntax-ns#langString
|
||||
rdf:langString rdf:type rdfs:Datatype ;
|
||||
rdfs:label "Language-tagged string"@en .
|
||||
|
||||
|
||||
### http://www.w3.org/2001/XMLSchema#boolean
|
||||
xsd:boolean rdf:type rdfs:Datatype ;
|
||||
rdfs:label "Boolean"@en .
|
||||
|
||||
|
||||
### http://www.w3.org/2001/XMLSchema#dateTime
|
||||
xsd:dateTime rdf:type rdfs:Datatype ;
|
||||
rdfs:comment "Date and time with or without timezone"@en .
|
||||
|
||||
|
||||
### http://www.w3.org/2001/XMLSchema#decimal
|
||||
xsd:decimal rdf:type rdfs:Datatype ;
|
||||
rdfs:comment "Arbitrary-precision decimal numbers"@en ;
|
||||
rdfs:label "Decimal"@en .
|
||||
|
||||
|
||||
### http://www.w3.org/2001/XMLSchema#integer
|
||||
xsd:integer rdf:type rdfs:Datatype ;
|
||||
rdfs:comment "Arbitrary-size integer numbers"@en ;
|
||||
rdfs:label "Integer"@en .
|
||||
|
||||
|
||||
### http://www.w3.org/2001/XMLSchema#nonNegativeInteger
|
||||
xsd:nonNegativeInteger rdf:type rdfs:Datatype ;
|
||||
rdfs:label "Non-negative Integer"@en .
|
||||
|
||||
|
||||
### http://www.w3.org/2001/XMLSchema#string
|
||||
xsd:string rdf:type rdfs:Datatype ;
|
||||
rdfs:label "String"@en .
|
||||
|
||||
|
||||
### http://www.w3.org/2001/XMLSchema#unsignedShort
|
||||
xsd:unsignedShort rdf:type rdfs:Datatype ;
|
||||
rdfs:label "Unsigned short"@en .
|
||||
|
||||
|
||||
#################################################################
|
||||
# Object Properties
|
||||
#################################################################
|
||||
|
||||
### http://fedora.info/definitions/v4/repository#hasParent
|
||||
fedora:hasParent rdf:type owl:ObjectProperty .
|
||||
|
||||
|
||||
### https://graphofliberty.org/2026/04/ont/associatedProperty
|
||||
:associatedProperty rdf:type owl:ObjectProperty ;
|
||||
rdfs:label "associated property"@en .
|
||||
|
||||
|
||||
### https://graphofliberty.org/2026/04/ont/indexedByField
|
||||
:indexedByField rdf:type owl:ObjectProperty ;
|
||||
rdfs:range :IndexDocumentField ;
|
||||
rdfs:comment "The property is associated with the given field in a full-text search database."@en ;
|
||||
rdfs:label "indexed by field"@en .
|
||||
|
||||
|
||||
### https://graphofliberty.org/2026/04/ont/template
|
||||
:template rdf:type owl:ObjectProperty ;
|
||||
rdfs:comment "A default set of triples used during the creation of new entities of the associated class."@en ;
|
||||
rdfs:label "has template"@en .
|
||||
|
||||
|
||||
#################################################################
|
||||
# Data properties
|
||||
#################################################################
|
||||
|
||||
### http://fedora.info/definitions/v4/repository#created
|
||||
fedora:created rdf:type owl:DatatypeProperty ;
|
||||
rdfs:subPropertyOf owl:topDataProperty .
|
||||
|
||||
|
||||
### http://fedora.info/definitions/v4/repository#createdBy
|
||||
fedora:createdBy rdf:type owl:DatatypeProperty ;
|
||||
rdfs:subPropertyOf owl:topDataProperty .
|
||||
|
||||
|
||||
### http://fedora.info/definitions/v4/repository#lastModified
|
||||
fedora:lastModified rdf:type owl:DatatypeProperty .
|
||||
|
||||
|
||||
### http://fedora.info/definitions/v4/repository#lastModifiedBy
|
||||
fedora:lastModifiedBy rdf:type owl:DatatypeProperty .
|
||||
|
||||
|
||||
### http://www.w3.org/ns/ldp#contains
|
||||
ldp:contains rdf:type owl:DatatypeProperty ;
|
||||
rdfs:subPropertyOf owl:topDataProperty .
|
||||
|
||||
|
||||
### https://graphofliberty.org/2026/04/ont/catalogId
|
||||
:catalogId rdf:type owl:DatatypeProperty ;
|
||||
rdfs:comment "An integer associated with the class for fast lookup in a database."@en ;
|
||||
rdfs:label "catalog id" .
|
||||
|
||||
|
||||
### https://graphofliberty.org/2026/04/ont/fieldLabel
|
||||
:fieldLabel rdf:type owl:DatatypeProperty ;
|
||||
rdfs:domain :IndexDocumentField ;
|
||||
rdfs:comment "The label of a field, which shall be displayed to the user."@en ;
|
||||
rdfs:label "field label"@en .
|
||||
|
||||
|
||||
### https://graphofliberty.org/2026/04/ont/fieldName
|
||||
:fieldName rdf:type owl:DatatypeProperty ;
|
||||
rdfs:domain :IndexDocumentField ;
|
||||
rdfs:comment "The name of the field, as defined in the full-text search document schema."@en ;
|
||||
rdfs:label "field name"@en .
|
||||
|
||||
|
||||
### https://graphofliberty.org/2026/04/ont/readOnly
|
||||
:readOnly rdf:type owl:DatatypeProperty ;
|
||||
rdfs:comment "Indicates that the property or class is read only (server managed) and should not be made editable in user-facing applications."@en ;
|
||||
rdfs:label "read only"@en .
|
||||
|
||||
|
||||
#################################################################
|
||||
# Classes
|
||||
#################################################################
|
||||
|
||||
### https://graphofliberty.org/2026/04/ont/Entity
|
||||
:Entity rdf:type owl:Class ;
|
||||
rdfs:label "Graph of Liberty Entity"@en .
|
||||
|
||||
|
||||
### https://graphofliberty.org/2026/04/ont/IndexDocumentField
|
||||
:IndexDocumentField rdf:type owl:Class ;
|
||||
rdfs:comment "Describes a single field present within a document that is indexed in a full-text search database."@en ;
|
||||
rdfs:label "Index Document Field"@en .
|
||||
|
||||
|
||||
#################################################################
|
||||
# Individuals
|
||||
#################################################################
|
||||
|
||||
### http://fedora.info/definitions/v4/repository#Container
|
||||
fedora:Container rdf:type owl:NamedIndividual ;
|
||||
:readOnly "true"^^xsd:boolean .
|
||||
|
||||
|
||||
### http://fedora.info/definitions/v4/repository#Resource
|
||||
fedora:Resource rdf:type owl:NamedIndividual ;
|
||||
:readOnly "true"^^xsd:boolean .
|
||||
|
||||
|
||||
### http://fedora.info/definitions/v4/repository#created
|
||||
fedora:created rdf:type owl:NamedIndividual ;
|
||||
:readOnly "true"^^xsd:boolean .
|
||||
|
||||
|
||||
### http://fedora.info/definitions/v4/repository#createdBy
|
||||
fedora:createdBy rdf:type owl:NamedIndividual ;
|
||||
:readOnly "true"^^xsd:boolean .
|
||||
|
||||
|
||||
### http://fedora.info/definitions/v4/repository#hasParent
|
||||
fedora:hasParent rdf:type owl:NamedIndividual ;
|
||||
:readOnly "true"^^xsd:boolean .
|
||||
|
||||
|
||||
### http://fedora.info/definitions/v4/repository#lastModified
|
||||
fedora:lastModified rdf:type owl:NamedIndividual ;
|
||||
:readOnly "true"^^xsd:boolean .
|
||||
|
||||
|
||||
### http://fedora.info/definitions/v4/repository#lastModifiedBy
|
||||
fedora:lastModifiedBy rdf:type owl:NamedIndividual ;
|
||||
:readOnly "true"^^xsd:boolean .
|
||||
|
||||
|
||||
### http://rdaregistry.info/Elements/x/P00028
|
||||
rdax:P00028 rdf:type owl:NamedIndividual ;
|
||||
:associatedProperty rdfs:label ,
|
||||
skos:definition ;
|
||||
:catalogId "2"^^xsd:nonNegativeInteger ;
|
||||
rdfs:label "has related entity of RDA entity"@en .
|
||||
|
||||
|
||||
### http://www.w3.org/1999/02/22-rdf-syntax-ns#Property
|
||||
rdf:Property rdf:type owl:NamedIndividual ;
|
||||
:associatedProperty rdfs:comment ,
|
||||
rdfs:label ;
|
||||
:catalogId "0"^^xsd:nonNegativeInteger .
|
||||
|
||||
|
||||
### http://www.w3.org/2000/01/rdf-schema#Class
|
||||
rdfs:Class rdf:type owl:NamedIndividual ;
|
||||
:associatedProperty rdfs:comment ,
|
||||
rdfs:label ;
|
||||
:catalogId "1"^^xsd:nonNegativeInteger .
|
||||
|
||||
|
||||
### http://www.w3.org/2000/01/rdf-schema#comment
|
||||
rdfs:comment rdf:type owl:NamedIndividual ;
|
||||
:indexedByField :Comment .
|
||||
|
||||
|
||||
### http://www.w3.org/2000/01/rdf-schema#label
|
||||
rdfs:label rdf:type owl:NamedIndividual ;
|
||||
:indexedByField :Label .
|
||||
|
||||
|
||||
### http://www.w3.org/2004/02/skos/core#definition
|
||||
skos:definition rdf:type owl:NamedIndividual ;
|
||||
:indexedByField :Definition .
|
||||
|
||||
|
||||
### http://www.w3.org/ns/ldp#BasicContainer
|
||||
ldp:BasicContainer rdf:type owl:NamedIndividual ;
|
||||
:readOnly "true"^^xsd:boolean .
|
||||
|
||||
|
||||
### http://www.w3.org/ns/ldp#Container
|
||||
ldp:Container rdf:type owl:NamedIndividual ;
|
||||
:readOnly "true"^^xsd:boolean .
|
||||
|
||||
|
||||
### http://www.w3.org/ns/ldp#RDFSource
|
||||
ldp:RDFSource rdf:type owl:NamedIndividual ;
|
||||
:readOnly "true"^^xsd:boolean .
|
||||
|
||||
|
||||
### http://www.w3.org/ns/ldp#Resource
|
||||
ldp:Resource rdf:type owl:NamedIndividual ;
|
||||
:readOnly "true"^^xsd:boolean .
|
||||
|
||||
|
||||
### http://www.w3.org/ns/ldp#contains
|
||||
ldp:contains rdf:type owl:NamedIndividual ;
|
||||
:readOnly "true"^^xsd:boolean .
|
||||
|
||||
|
||||
### https://graphofliberty.org/2026/04/ont/Comment
|
||||
:Comment rdf:type owl:NamedIndividual ,
|
||||
:IndexDocumentField ;
|
||||
:fieldLabel "Comment"@en ;
|
||||
:fieldName "comment" ;
|
||||
rdfs:label "Comment Field"@en .
|
||||
|
||||
|
||||
### https://graphofliberty.org/2026/04/ont/Definition
|
||||
:Definition rdf:type owl:NamedIndividual ,
|
||||
:IndexDocumentField ;
|
||||
:fieldLabel "Definition"@en ;
|
||||
:fieldName "definition" ;
|
||||
rdfs:label "Definition Field"@en .
|
||||
|
||||
|
||||
### https://graphofliberty.org/2026/04/ont/Label
|
||||
:Label rdf:type owl:NamedIndividual ,
|
||||
:IndexDocumentField ;
|
||||
:fieldLabel "Label"@en ;
|
||||
:fieldName "label" ;
|
||||
rdfs:label "Label Field"@en .
|
||||
|
||||
|
||||
### Generated by the OWL API (version 4.5.29.2024-05-13T12:11:03Z) https://github.com/owlcs/owlapi
|
||||
+32
-19
@@ -1,15 +1,16 @@
|
||||
use crate::error;
|
||||
use crate::rdf::vocab::gl;
|
||||
use oxigraph::model::vocab::{rdf, rdfs, xsd};
|
||||
use oxigraph::model::{LiteralRef, NamedNode, NamedNodeRef, NamedOrBlankNode, NamedOrBlankNodeRef, Term, TermRef, Triple, TripleRef};
|
||||
use oxigraph::model::{Dataset, LiteralRef, NamedNode, NamedNodeRef, NamedOrBlankNode, NamedOrBlankNodeRef, Term, TermRef, Triple, TripleRef};
|
||||
use oxigraph::sparql::{QueryResults, SparqlEvaluator};
|
||||
use std::collections::{BTreeMap, HashMap, HashSet};
|
||||
use std::collections::{BTreeMap, BTreeSet, HashMap, HashSet};
|
||||
use std::fmt::Display;
|
||||
use std::path::{Path, PathBuf};
|
||||
use std::sync::LazyLock;
|
||||
use oxigraph::store::Store;
|
||||
use tracing::debug_span;
|
||||
use tracing::{debug_span, info};
|
||||
use crate::rdf::{conversion, materialize};
|
||||
use crate::rdf::conversion::{quad_into_term, term_into_named_node, term_into_string, term_to_named_node};
|
||||
use crate::rdf::language::LanguageCondition;
|
||||
|
||||
static PREFIXES: LazyLock<BTreeMap<String, String>> = LazyLock::new(|| {
|
||||
@@ -114,14 +115,6 @@ impl Display for LabeledIri {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct Entity {
|
||||
pub label: String,
|
||||
pub comment: Option<String>,
|
||||
pub catalog_id: u64,
|
||||
pub properties: HashSet<NamedNode>,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct IndexField {
|
||||
pub name: String,
|
||||
@@ -148,13 +141,13 @@ impl Ontology {
|
||||
let language_filter = language.to_filter_expression("fieldValue");
|
||||
let query = format!(r#"SELECT ?individual ?catalogId ?fieldName ?fieldValue
|
||||
WHERE {{
|
||||
?entity a gl:Entity ;
|
||||
?class a gl:SearchableClass ;
|
||||
gl:catalogId ?catalogId ;
|
||||
gl:associatedProperty ?property .
|
||||
|
||||
?property gl:indexedByField/gl:fieldName ?fieldName .
|
||||
|
||||
?individual a ?entity ;
|
||||
?individual a ?class ;
|
||||
?property ?fieldValue .
|
||||
|
||||
{language_filter}
|
||||
@@ -250,9 +243,9 @@ WHERE {{
|
||||
pub fn info(&self, iri: &NamedNode, language: &LanguageCondition) -> LabeledIri {
|
||||
let label = self.store.quads_for_pattern(Some(iri.as_ref().into()), Some(rdfs::LABEL), None, None)
|
||||
.filter_map(Result::ok)
|
||||
.map(conversion::quad_into_term)
|
||||
.map(quad_into_term)
|
||||
.filter(|term| language.primary_matches_term(term))
|
||||
.filter_map(conversion::term_into_string)
|
||||
.filter_map(term_into_string)
|
||||
.next()
|
||||
.unwrap_or_default();
|
||||
|
||||
@@ -262,15 +255,15 @@ WHERE {{
|
||||
}
|
||||
}
|
||||
|
||||
pub fn labeled_entities(&self, language: &LanguageCondition) -> impl Iterator<Item = LabeledIri> {
|
||||
self.store.quads_for_pattern(None, Some(rdf::TYPE), Some(gl::ENTITY.into()), None)
|
||||
pub fn searchable_classes(&self, language: &LanguageCondition) -> impl Iterator<Item = LabeledIri> {
|
||||
self.store.quads_for_pattern(None, Some(rdf::TYPE), Some(gl::SEARCHABLE.into()), None)
|
||||
.filter_map(Result::ok)
|
||||
.filter_map(|quad| {
|
||||
let label = self.store.quads_for_pattern(Some(quad.subject.as_ref().into()), Some(rdfs::LABEL), None, None)
|
||||
.filter_map(Result::ok)
|
||||
.map(conversion::quad_into_term)
|
||||
.map(quad_into_term)
|
||||
.filter(|term| language.primary_matches_term(term))
|
||||
.filter_map(conversion::term_into_string)
|
||||
.filter_map(term_into_string)
|
||||
.next();
|
||||
if let Some(label) = label && let NamedOrBlankNode::NamedNode(subject) = quad.subject {
|
||||
Some(LabeledIri {
|
||||
@@ -281,6 +274,15 @@ WHERE {{
|
||||
})
|
||||
}
|
||||
|
||||
pub fn subclasses_of(&self, class: &NamedNode) -> BTreeSet<NamedNode> {
|
||||
self.store.quads_for_pattern(None, Some(rdfs::SUB_CLASS_OF), Some(class.into()), None)
|
||||
.filter_map(Result::ok)
|
||||
.filter_map(|quad| if let NamedOrBlankNode::NamedNode(subject) = quad.subject {
|
||||
Some(subject)
|
||||
} else { None })
|
||||
.collect()
|
||||
}
|
||||
|
||||
pub fn datatypes(&self) -> impl Iterator<Item = NamedNode> {
|
||||
self.store
|
||||
.quads_for_pattern(
|
||||
@@ -311,6 +313,17 @@ WHERE {{
|
||||
.count() >= 1
|
||||
}
|
||||
|
||||
pub fn exclude_read_only(&self) -> impl Fn(TripleRef<'_>) -> bool + 'static {
|
||||
let true_term = TermRef::Literal(LiteralRef::new_typed_literal("true", xsd::BOOLEAN));
|
||||
let dataset = self.store
|
||||
.quads_for_pattern(None, Some(gl::READ_ONLY), Some(true_term), None)
|
||||
.filter_map(Result::ok)
|
||||
.collect::<Dataset>();
|
||||
move |triple| {
|
||||
dataset.quads_for_subject(triple.subject).count() == 0
|
||||
}
|
||||
}
|
||||
|
||||
pub fn template_triples<'a>(
|
||||
&'a self,
|
||||
class: NamedNodeRef<'a>,
|
||||
|
||||
@@ -10,6 +10,9 @@ pub mod gl {
|
||||
pub const CATALOG_ID: NamedNodeRef =
|
||||
NamedNodeRef::new_unchecked("https://graphofliberty.org/2026/04/ont/catalogId");
|
||||
|
||||
pub const SEARCHABLE: NamedNodeRef =
|
||||
NamedNodeRef::new_unchecked("https://graphofliberty.org/2026/04/ont/Searchable");
|
||||
|
||||
pub const ENTITY: NamedNodeRef =
|
||||
NamedNodeRef::new_unchecked("https://graphofliberty.org/2026/04/ont/Entity");
|
||||
|
||||
@@ -18,9 +21,6 @@ pub mod gl {
|
||||
|
||||
pub const READ_ONLY: NamedNodeRef =
|
||||
NamedNodeRef::new_unchecked("https://graphofliberty.org/2026/04/ont/readOnly");
|
||||
|
||||
/*pub const INDEX_FIELD: NamedNodeRef =
|
||||
NamedNodeRef::new_unchecked("https://graphofliberty.org/2026/04/ont/IndexField");*/
|
||||
}
|
||||
|
||||
pub mod owl {
|
||||
|
||||
Reference in New Issue
Block a user