Skip to content

Commit f58ffda

Browse files
authored
Merge pull request #253 from ncbo/develop
Develop to master merge, release v6.5.0
2 parents 098c1e1 + d55bddd commit f58ffda

27 files changed

Lines changed: 1480 additions & 478 deletions

bin/owlapi-wrapper-1.5.0.jar

100644100755
File mode changed.

dip.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ interaction:
4040

4141
test-ag:
4242
description: Run minitest unit tests
43-
service: ruby-ag
43+
service: ruby-agraph
4444
command: bundle exec rake test
4545

4646

lib/ontologies_linked_data.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@
5252
end
5353

5454
# We need to require deterministic - that is why we have the sort.
55-
models = Dir.glob("#{project_root}/ontologies_linked_data/models/concerns//**/*.rb").sort
55+
models = Dir.glob("#{project_root}/ontologies_linked_data/models/concerns/**/*.rb").sort
5656
models.each do |m|
5757
require m
5858
end
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
module LinkedData
2+
module Concerns
3+
module Concept
4+
module InCollection
5+
def self.included(base)
6+
base.serialize_methods :isInActiveCollection
7+
end
8+
9+
def isInActiveCollection
10+
@isInActiveCollection
11+
end
12+
13+
def inCollection?(collection)
14+
self.memberOf.include?(collection)
15+
end
16+
17+
def load_is_in_collection(collections = [])
18+
included = collections.select { |s| inCollection?(s) }
19+
@isInActiveCollection = included
20+
end
21+
22+
end
23+
end
24+
end
25+
end
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
module LinkedData
2+
module Concerns
3+
module Concept
4+
module InScheme
5+
def self.included(base)
6+
base.serialize_methods :isInActiveScheme
7+
end
8+
9+
def isInActiveScheme
10+
@isInActiveScheme
11+
end
12+
13+
def inScheme?(scheme)
14+
self.inScheme.include?(scheme)
15+
end
16+
17+
def load_is_in_scheme(schemes = [])
18+
included = schemes.select { |s| inScheme?(s) }
19+
included = [self.submission.get_main_concept_scheme] if included.empty? && schemes&.empty?
20+
@isInActiveScheme = included
21+
end
22+
23+
end
24+
end
25+
end
26+
end
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
module LinkedData
2+
module Concerns
3+
module Concept
4+
module Sort
5+
module ClassMethods
6+
def compare_classes(class_a, class_b)
7+
label_a = ""
8+
label_b = ""
9+
class_a.bring(:prefLabel) if class_a.bring?(:prefLabel)
10+
class_b.bring(:prefLabel) if class_b.bring?(:prefLabel)
11+
12+
begin
13+
label_a = class_a.prefLabel unless (class_a.prefLabel.nil? || class_a.prefLabel.empty?)
14+
rescue Goo::Base::AttributeNotLoaded
15+
label_a = ""
16+
end
17+
18+
begin
19+
label_b = class_b.prefLabel unless (class_b.prefLabel.nil? || class_b.prefLabel.empty?)
20+
rescue Goo::Base::AttributeNotLoaded
21+
label_b = ""
22+
end
23+
24+
label_a = class_a.id if label_a.empty?
25+
label_b = class_b.id if label_b.empty?
26+
27+
[label_a.downcase] <=> [label_b.downcase]
28+
end
29+
30+
def sort_classes(classes)
31+
classes.sort { |class_a, class_b| compare_classes(class_a, class_b) }
32+
end
33+
34+
def sort_tree_children(root_node)
35+
sort_classes!(root_node.children)
36+
root_node.children.each { |ch| sort_tree_children(ch) }
37+
end
38+
39+
private
40+
41+
42+
43+
def sort_classes!(classes)
44+
classes.sort! { |class_a, class_b| LinkedData::Models::Class.compare_classes(class_a, class_b) }
45+
classes
46+
end
47+
end
48+
49+
def self.included(base)
50+
base.extend(ClassMethods)
51+
end
52+
end
53+
end
54+
end
55+
end
Lines changed: 139 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,139 @@
1+
module LinkedData
2+
module Concerns
3+
module Concept
4+
module Tree
5+
def tree(concept_schemes: [], concept_collections: [], roots: nil)
6+
bring(parents: [:prefLabel]) if bring?(:parents)
7+
return self if parents.nil? || parents.empty?
8+
extra_include = [:hasChildren, :isInActiveScheme, :isInActiveCollection]
9+
roots = self.submission.roots( extra_include, concept_schemes:concept_schemes) if roots.nil?
10+
path = path_to_root(roots)
11+
threshold = 99
12+
13+
return self if path.nil?
14+
15+
attrs_to_load = %i[prefLabel synonym obsolete]
16+
attrs_to_load << :subClassOf if submission.hasOntologyLanguage.obo?
17+
attrs_to_load += self.class.concept_is_in_attributes if submission.skos?
18+
self.class.in(submission)
19+
.models(path)
20+
.include(attrs_to_load).all
21+
load_children(path, threshold: threshold)
22+
23+
path.reverse!
24+
path.last.instance_variable_set("@children", [])
25+
26+
childrens_hash = {}
27+
path.each do |m|
28+
next if m.id.to_s["#Thing"]
29+
m.children.each do |c|
30+
childrens_hash[c.id.to_s] = c
31+
c.load_computed_attributes(to_load:extra_include ,
32+
options: {schemes: concept_schemes, collections: concept_collections})
33+
end
34+
m.load_computed_attributes(to_load:extra_include ,
35+
options: {schemes: concept_schemes, collections: concept_collections})
36+
end
37+
38+
load_children(childrens_hash.values, threshold: threshold)
39+
40+
build_tree(path)
41+
end
42+
43+
def tree_sorted(concept_schemes: [], concept_collections: [], roots: nil)
44+
tr = tree(concept_schemes: concept_schemes, concept_collections: concept_collections, roots: roots)
45+
self.class.sort_tree_children(tr)
46+
tr
47+
end
48+
49+
def paths_to_root(tree: false, roots: nil)
50+
bring(parents: [:prefLabel, :synonym, :definition]) if bring?(:parents)
51+
return [] if parents.nil? || parents.empty?
52+
53+
paths = [[self]]
54+
traverse_path_to_root(self.parents.dup, paths, 0, tree, roots) unless tree_root?(self, roots)
55+
paths.each do |p|
56+
p.reverse!
57+
end
58+
paths
59+
end
60+
61+
def path_to_root(roots)
62+
paths = [[self]]
63+
paths = paths_to_root(tree: true, roots: roots)
64+
#select one path that gets to root
65+
path = nil
66+
paths.each do |p|
67+
p.reverse!
68+
unless (p.map { |x| x.id.to_s } & roots.map { |x| x.id.to_s }).empty?
69+
path = p
70+
break
71+
end
72+
end
73+
74+
if path.nil?
75+
# do one more check for root classes that don't get returned by the submission.roots call
76+
paths.each do |p|
77+
root_node = p.last
78+
root_parents = root_node.parents
79+
80+
if root_parents.empty?
81+
path = p
82+
break
83+
end
84+
end
85+
end
86+
87+
path
88+
end
89+
90+
def tree_root?(concept, roots)
91+
(roots &&roots.map{|r| r.id}.include?(concept.id)) || concept.id.to_s["#Thing"]
92+
end
93+
94+
private
95+
96+
def load_children(concepts, threshold: 99)
97+
LinkedData::Models::Class
98+
.partially_load_children(concepts, threshold, submission)
99+
end
100+
101+
def build_tree(path)
102+
root_node = path.first
103+
tree_node = path.first
104+
path.delete_at(0)
105+
while tree_node &&
106+
!tree_node.id.to_s["#Thing"] &&
107+
!tree_node.children.empty? && (!path.empty?) do
108+
next_tree_node = nil
109+
tree_node.load_has_children
110+
tree_node.children.each_index do |i|
111+
if tree_node.children[i].id.to_s == path.first.id.to_s
112+
next_tree_node = path.first
113+
children = tree_node.children.dup
114+
children[i] = path.first
115+
tree_node.instance_variable_set("@children", children)
116+
children.each do |c|
117+
c.load_has_children
118+
end
119+
else
120+
tree_node.children[i].instance_variable_set("@children", [])
121+
end
122+
end
123+
124+
if !path.empty? && next_tree_node.nil?
125+
tree_node.children << path.shift
126+
end
127+
tree_node = next_tree_node
128+
path.delete_at(0)
129+
end
130+
131+
root_node
132+
end
133+
134+
end
135+
end
136+
137+
end
138+
end
139+
Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
1+
module LinkedData
2+
module Models
3+
module SKOS
4+
module RootsFetcher
5+
6+
def skos_roots(concept_schemes, page, paged, pagesize)
7+
classes = []
8+
class_ids, count = roots_by_has_top_concept(concept_schemes, page, paged, pagesize)
9+
10+
class_ids, count = roots_by_top_concept_of(concept_schemes, page, paged, pagesize) if class_ids.empty?
11+
12+
class_ids.each do |id|
13+
classes << LinkedData::Models::Class.find(id).in(self).disable_rules.first
14+
end
15+
16+
classes = Goo::Base::Page.new(page, pagesize, count, classes) if paged
17+
classes
18+
end
19+
20+
private
21+
22+
def roots_by_query(query_body, page, paged, pagesize)
23+
root_skos = <<-eos
24+
SELECT DISTINCT ?root WHERE {
25+
GRAPH #{self.id.to_ntriples} {
26+
#{query_body}
27+
}}
28+
eos
29+
count = 0
30+
31+
count, root_skos = add_pagination(query_body, page, pagesize, root_skos) if paged
32+
33+
#needs to get cached
34+
class_ids = []
35+
36+
Goo.sparql_query_client.query(root_skos, { graphs: [self.id] }).each_solution do |s|
37+
class_ids << s[:root]
38+
end
39+
40+
[class_ids, count]
41+
end
42+
43+
def roots_by_has_top_concept(concept_schemes, page, paged, pagesize)
44+
query_body = <<-eos
45+
?x #{RDF::SKOS[:hasTopConcept].to_ntriples} ?root .
46+
#{concept_schemes_filter(concept_schemes)}
47+
eos
48+
roots_by_query query_body, page, paged, pagesize
49+
end
50+
51+
def roots_by_top_concept_of(concept_schemes, page, paged, pagesize)
52+
query_body = <<-eos
53+
?root #{RDF::SKOS[:topConceptOf].to_ntriples} ?x.
54+
#{concept_schemes_filter(concept_schemes)}
55+
eos
56+
roots_by_query query_body, page, paged, pagesize
57+
end
58+
59+
def add_pagination(query_body, page, pagesize, root_skos)
60+
count = count_roots(query_body)
61+
62+
offset = (page - 1) * pagesize
63+
root_skos = "#{root_skos} LIMIT #{pagesize} OFFSET #{offset}"
64+
[count, root_skos]
65+
end
66+
67+
def count_roots(query_body)
68+
query = <<-eos
69+
SELECT (COUNT(?x) as ?count) WHERE {
70+
GRAPH #{self.id.to_ntriples} {
71+
#{query_body}
72+
}}
73+
eos
74+
rs = Goo.sparql_query_client.query(query)
75+
count = 0
76+
rs.each do |sol|
77+
count = sol[:count].object
78+
end
79+
count
80+
end
81+
82+
def concept_schemes_filter(concept_schemes)
83+
concept_schemes = current_schemes(concept_schemes)
84+
concept_schemes = concept_schemes.map { |x| RDF::URI.new(x.to_s).to_ntriples }
85+
concept_schemes.empty? ? '' : "FILTER (?x IN (#{concept_schemes.join(',')}))"
86+
end
87+
88+
def current_schemes(concept_schemes)
89+
if concept_schemes.nil? || concept_schemes.empty?
90+
main_concept_scheme = get_main_concept_scheme
91+
concept_schemes = main_concept_scheme ? [main_concept_scheme] : []
92+
end
93+
concept_schemes
94+
end
95+
96+
end
97+
end
98+
end
99+
end
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
module LinkedData
2+
module Models
3+
module SKOS
4+
module ConceptSchemes
5+
def get_main_concept_scheme(default_return: ontology_uri)
6+
all = all_concepts_schemes
7+
unless all.nil?
8+
all = all.map { |x| x.id }
9+
return default_return if all.include?(ontology_uri)
10+
end
11+
end
12+
13+
def all_concepts_schemes
14+
LinkedData::Models::SKOS::Scheme.in(self).all
15+
end
16+
end
17+
end
18+
end
19+
end
20+

0 commit comments

Comments
 (0)