iqvoc 4.0.8 → 4.0.9
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG.md +11 -0
- data/Gemfile +5 -1
- data/Gemfile.lock +35 -18
- data/README.md +3 -2
- data/app/assets/stylesheets/iqvoc/components.css.scss +0 -6
- data/app/controllers/collections_controller.rb +30 -17
- data/app/controllers/concepts/alphabetical_controller.rb +15 -9
- data/app/{models/collection/member/concept.rb → controllers/concepts/expired_controller.rb} +13 -15
- data/app/controllers/concepts/hierarchical_controller.rb +3 -0
- data/app/controllers/concepts_controller.rb +2 -3
- data/app/controllers/instance_configuration_controller.rb +5 -6
- data/app/controllers/search_results_controller.rb +1 -2
- data/app/helpers/application_helper.rb +1 -5
- data/app/helpers/concepts_helper.rb +1 -1
- data/app/helpers/rdf_helper.rb +1 -1
- data/app/helpers/widget_helper.rb +3 -3
- data/app/models/collection/base.rb +64 -46
- data/app/models/collection/member/base.rb +12 -0
- data/app/models/collection/member/skos/base.rb +13 -12
- data/app/models/collection/skos/base.rb +1 -1
- data/app/models/collection/{member/collection.rb → skos/unordered.rb} +1 -16
- data/app/models/collection/unordered.rb +7 -0
- data/app/models/concept/base.rb +26 -107
- data/app/models/concept/relation/base.rb +4 -0
- data/app/models/concept/relation/skos/base.rb +17 -7
- data/app/models/concept/skos/base.rb +10 -1
- data/app/models/concept/skos/scheme.rb +1 -1
- data/app/models/concept/validations.rb +117 -0
- data/app/models/label/base.rb +4 -3
- data/app/models/labeling/skos/base.rb +24 -13
- data/app/models/match/skos/base.rb +24 -5
- data/app/models/note/skos/base.rb +17 -14
- data/app/views/collections/_form.html.erb +2 -2
- data/app/views/collections/_header.html.erb +2 -2
- data/app/views/collections/_sidebar.html.erb +3 -3
- data/app/views/collections/index.html.erb +1 -1
- data/app/views/collections/show.html.erb +1 -1
- data/app/views/collections/show.iqrdf +1 -1
- data/app/views/concepts/alphabetical/index.html.erb +1 -1
- data/app/views/concepts/expired/index.html.erb +16 -0
- data/app/views/concepts/notifications/_referenced_concepts.html.erb +1 -1
- data/app/views/concepts/sidebars/_plural.html.erb +4 -0
- data/app/views/dashboard/index.html.erb +1 -1
- data/app/views/layouts/_controls.html.erb +25 -24
- data/app/views/layouts/_navigation.html.erb +1 -1
- data/app/views/layouts/application.html.erb +0 -6
- data/app/views/partials/concept/_edit_link_base.html.erb +2 -1
- data/app/views/partials/labeling/skos/_base.html.erb +1 -2
- data/app/views/partials/note/_edit_base.html.erb +1 -1
- data/app/views/partials/note/skos/_edit_change_note.html.erb +1 -1
- data/app/views/rdf/scheme.iqrdf +1 -1
- data/app/views/search_results/_header.html.erb +2 -2
- data/app/views/search_results/_sidebar.html.erb +2 -2
- data/app/views/search_results/index.html.erb +1 -1
- data/app/views/triplestore_sync/index.html.erb +2 -2
- data/config/locales/de.yml +9 -2
- data/config/locales/en.yml +11 -4
- data/config/locales/pt.yml +8 -3
- data/config/routes.rb +15 -6
- data/db/migrate/20130227145825_fix_collection_type.rb +10 -0
- data/db/schema.rb +1 -1
- data/lib/generators/app/template.rb +20 -0
- data/lib/iqvoc/configuration/collection.rb +5 -5
- data/lib/iqvoc/configuration/concept.rb +7 -7
- data/lib/iqvoc/configuration/core.rb +11 -10
- data/lib/iqvoc/controller_extensions.rb +2 -5
- data/lib/iqvoc/inline_data_helper.rb +25 -3
- data/lib/iqvoc/instance_configuration.rb +1 -1
- data/lib/iqvoc/rdfapi.rb +56 -0
- data/lib/iqvoc/skos_importer.rb +88 -40
- data/lib/iqvoc/version.rb +1 -1
- data/lib/multi_logger.rb +38 -0
- data/lib/tasks/importer.rake +6 -1
- data/test/integration/browse_concepts_and_labels_test.rb +16 -0
- data/test/integration/instance_configuration_test.rb +5 -5
- data/test/integration/search_test.rb +18 -17
- data/test/unit/concept_test.rb +53 -4
- data/test/unit/inline_data_test.rb +61 -0
- data/test/unit/origin_test.rb +1 -1
- data/test/unit/rdfapi_test.rb +83 -0
- data/test/unit/skos_import_test.rb +1 -1
- data/{public/assets/jquery-ui → vendor/assets/images}/ui-bg_flat_0_aaaaaa_40x100.png +0 -0
- data/{public/assets/jquery-ui → vendor/assets/images}/ui-bg_flat_55_fbec88_40x100.png +0 -0
- data/{public/assets/jquery-ui → vendor/assets/images}/ui-bg_glass_75_d0e5f5_1x400.png +0 -0
- data/{public/assets/jquery-ui → vendor/assets/images}/ui-bg_glass_85_dfeffc_1x400.png +0 -0
- data/{public/assets/jquery-ui → vendor/assets/images}/ui-bg_glass_95_fef1ec_1x400.png +0 -0
- data/{public/assets/jquery-ui → vendor/assets/images}/ui-bg_gloss-wave_55_5c9ccc_500x100.png +0 -0
- data/{public/assets/jquery-ui → vendor/assets/images}/ui-bg_inset-hard_100_f5f8f9_1x100.png +0 -0
- data/{public/assets/jquery-ui → vendor/assets/images}/ui-bg_inset-hard_100_fcfdfd_1x100.png +0 -0
- data/{public/assets/jquery-ui → vendor/assets/images}/ui-icons_217bc0_256x240.png +0 -0
- data/{public/assets/jquery-ui → vendor/assets/images}/ui-icons_2e83ff_256x240.png +0 -0
- data/{public/assets/jquery-ui → vendor/assets/images}/ui-icons_469bdd_256x240.png +0 -0
- data/{public/assets/jquery-ui → vendor/assets/images}/ui-icons_6da8d5_256x240.png +0 -0
- data/{public/assets/jquery-ui → vendor/assets/images}/ui-icons_cd0a0a_256x240.png +0 -0
- data/{public/assets/jquery-ui → vendor/assets/images}/ui-icons_d8e7f3_256x240.png +0 -0
- data/{public/assets/jquery-ui → vendor/assets/images}/ui-icons_f9bd01_256x240.png +0 -0
- data/vendor/assets/stylesheets/{jquery-ui-1.8.23.custom.css → jquery-ui-1.8.23.custom.css.scss} +17 -17
- metadata +29 -131
- data/app/controllers/collections/hierarchical_controller.rb +0 -44
- data/public/assets/ajax-loader-dada1fbb71d7fb80d8dde7a031ae6cd0.gif +0 -0
- data/public/assets/ajax-loader.gif +0 -0
- data/public/assets/arrow_down-07c5dea12928d65fcc31c08279366170.gif +0 -0
- data/public/assets/arrow_down.gif +0 -0
- data/public/assets/arrow_up-51ede92c113b9a870e7a306907360ba8.gif +0 -0
- data/public/assets/arrow_up.gif +0 -0
- data/public/assets/bootstrap/bootstrap-2012a68e8267282c0a2c177d7005ae6d.css +0 -9
- data/public/assets/bootstrap/bootstrap-2012a68e8267282c0a2c177d7005ae6d.css.gz +0 -0
- data/public/assets/bootstrap/bootstrap-35fd77cdf54a8cb63a39d8d0cea7a746.js +0 -19
- data/public/assets/bootstrap/bootstrap-35fd77cdf54a8cb63a39d8d0cea7a746.js.gz +0 -0
- data/public/assets/bootstrap/bootstrap-responsive-609b376f4bb032588c054b563d4bca1f.css +0 -9
- data/public/assets/bootstrap/bootstrap-responsive-609b376f4bb032588c054b563d4bca1f.css.gz +0 -0
- data/public/assets/bootstrap/bootstrap-responsive.css +0 -9
- data/public/assets/bootstrap/bootstrap-responsive.css.gz +0 -0
- data/public/assets/bootstrap/bootstrap.css +0 -9
- data/public/assets/bootstrap/bootstrap.css.gz +0 -0
- data/public/assets/bootstrap/bootstrap.js +0 -19
- data/public/assets/bootstrap/bootstrap.js.gz +0 -0
- data/public/assets/bootstrap/glyphicons-halflings-0e7ff93d8f48fe1f5f762e4312e78da7.png +0 -0
- data/public/assets/bootstrap/glyphicons-halflings-white-ef3d5b8d6a297804352b4a46fdb5466d.png +0 -0
- data/public/assets/bootstrap/glyphicons-halflings-white.png +0 -0
- data/public/assets/bootstrap/glyphicons-halflings.png +0 -0
- data/public/assets/file-58ce0b58f19dfe871b25270e98cff66c.gif +0 -0
- data/public/assets/file.gif +0 -0
- data/public/assets/folder-5c5b1fd2f1ece710f9159f05cc2aaaa8.gif +0 -0
- data/public/assets/folder-closed-8b61fc55011d534f0216c1150994f229.gif +0 -0
- data/public/assets/folder-closed.gif +0 -0
- data/public/assets/folder.gif +0 -0
- data/public/assets/html5-05e1be9157c8366db72fb7a1bcc8daff.js +0 -3
- data/public/assets/html5-05e1be9157c8366db72fb7a1bcc8daff.js.gz +0 -0
- data/public/assets/html5.js +0 -3
- data/public/assets/html5.js.gz +0 -0
- data/public/assets/iqvoc/ie_fixes-6a106c21d979ccdd1f6bf1cb129a0e69.css +0 -1
- data/public/assets/iqvoc/ie_fixes-6a106c21d979ccdd1f6bf1cb129a0e69.css.gz +0 -0
- data/public/assets/iqvoc/ie_fixes.css +0 -1
- data/public/assets/iqvoc/ie_fixes.css.gz +0 -0
- data/public/assets/iqvoc_logo-316859a511c646918fe75e92fa0bf6ac.png +0 -0
- data/public/assets/iqvoc_logo.png +0 -0
- data/public/assets/jquery-ui/ui-bg_flat_0_aaaaaa_40x100-a1eb3e0764573ed4b261ca742ed96ac3.png +0 -0
- data/public/assets/jquery-ui/ui-bg_flat_55_fbec88_40x100-439ee8e6c8ce855f43ed4d7b90684720.png +0 -0
- data/public/assets/jquery-ui/ui-bg_glass_75_d0e5f5_1x400-9357836db77954d0d8c5feb259635223.png +0 -0
- data/public/assets/jquery-ui/ui-bg_glass_85_dfeffc_1x400-7beb11d1590fb2fb1ef5c754100a078a.png +0 -0
- data/public/assets/jquery-ui/ui-bg_glass_95_fef1ec_1x400-c723e9a2b50006c6054836a10b76bb84.png +0 -0
- data/public/assets/jquery-ui/ui-bg_gloss-wave_55_5c9ccc_500x100-cb26f48ac4912c23ce301c69c474d306.png +0 -0
- data/public/assets/jquery-ui/ui-bg_inset-hard_100_f5f8f9_1x100-519299e2aa31bffdd4fed34b4fac603d.png +0 -0
- data/public/assets/jquery-ui/ui-bg_inset-hard_100_fcfdfd_1x100-27e08524d3d56bb59e354435b663c3ac.png +0 -0
- data/public/assets/jquery-ui/ui-icons_217bc0_256x240-ed26778199d8722ae064038a1e841bc8.png +0 -0
- data/public/assets/jquery-ui/ui-icons_2e83ff_256x240-94086d0ce953eb0887ab1b8140903af9.png +0 -0
- data/public/assets/jquery-ui/ui-icons_469bdd_256x240-1c055f2d65517ef8faf1d1999c8ac2fa.png +0 -0
- data/public/assets/jquery-ui/ui-icons_6da8d5_256x240-8f5b417c5604f1b7b5965c98754c33b9.png +0 -0
- data/public/assets/jquery-ui/ui-icons_cd0a0a_256x240-8b44e266bdc1f57f1393579591f89222.png +0 -0
- data/public/assets/jquery-ui/ui-icons_d8e7f3_256x240-1b415e411069df902e6f417cc014172c.png +0 -0
- data/public/assets/jquery-ui/ui-icons_f9bd01_256x240-4553d0576c0498ca4c776aa77aa80833.png +0 -0
- data/public/assets/json2-b08b7b9af3e715f42c088ac728f62a2b.js +0 -157
- data/public/assets/json2-b08b7b9af3e715f42c088ac728f62a2b.js.gz +0 -0
- data/public/assets/json2.js +0 -157
- data/public/assets/json2.js.gz +0 -0
- data/public/assets/manifest-3ce8edde69d5d291841ef7c49daaa9cb.js +0 -21
- data/public/assets/manifest-3ce8edde69d5d291841ef7c49daaa9cb.js.gz +0 -0
- data/public/assets/manifest-c0eca563fd9f16907d302af9a2dcae6b.css +0 -51
- data/public/assets/manifest-c0eca563fd9f16907d302af9a2dcae6b.css.gz +0 -0
- data/public/assets/manifest.css +0 -51
- data/public/assets/manifest.css.gz +0 -0
- data/public/assets/manifest.js +0 -21
- data/public/assets/manifest.js.gz +0 -0
- data/public/assets/manifest.yml +0 -47
- data/public/assets/minus-1d0fae0720bab52bd98598218e8345c0.gif +0 -0
- data/public/assets/minus.gif +0 -0
- data/public/assets/plus-1a29e46532f839ed9c977ef4613d079f.gif +0 -0
- data/public/assets/plus.gif +0 -0
- data/public/assets/spinner_16x16-17dcf941457ae4e702f4600e714b21c1.gif +0 -0
- data/public/assets/spinner_16x16.gif +0 -0
- data/public/assets/spinner_24x24-78c707c1921b93962ea5edd7f4a74134.gif +0 -0
- data/public/assets/spinner_24x24.gif +0 -0
- data/public/assets/treeview-black-c46d96020e5d79c652af0fb0c6656384.gif +0 -0
- data/public/assets/treeview-black-line-0903c58efd34c3203d132e6f873049f6.gif +0 -0
- data/public/assets/treeview-black-line.gif +0 -0
- data/public/assets/treeview-black.gif +0 -0
- data/public/assets/treeview-default-ee6298d311205d21dc57c01c0696df70.gif +0 -0
- data/public/assets/treeview-default-line-2c4106cfd4d322c6e6565f80702c27cb.gif +0 -0
- data/public/assets/treeview-default-line.gif +0 -0
- data/public/assets/treeview-default.gif +0 -0
- data/public/assets/treeview-famfamfam-20dfef13cd5fd1e08fb61ee68eb9d3fa.gif +0 -0
- data/public/assets/treeview-famfamfam-line-a02cce2b80977e066df83137aae71fa8.gif +0 -0
- data/public/assets/treeview-famfamfam-line.gif +0 -0
- data/public/assets/treeview-famfamfam.gif +0 -0
- data/public/assets/treeview-gray-01bfdcd116e081e23daf13024fd3e4e0.gif +0 -0
- data/public/assets/treeview-gray-line-029b3a7b92ed10ea6c4b6289cb9fa0e3.gif +0 -0
- data/public/assets/treeview-gray-line.gif +0 -0
- data/public/assets/treeview-gray.gif +0 -0
- data/public/assets/treeview-red-2a5abbce598d05c864d845998381eef6.gif +0 -0
- data/public/assets/treeview-red-line-f51e6c30aa3b0ff856900ba85d769f1c.gif +0 -0
- data/public/assets/treeview-red-line.gif +0 -0
- data/public/assets/treeview-red.gif +0 -0
- data/vendor/assets/images/jquery-ui/ui-bg_flat_0_aaaaaa_40x100.png +0 -0
- data/vendor/assets/images/jquery-ui/ui-bg_flat_55_fbec88_40x100.png +0 -0
- data/vendor/assets/images/jquery-ui/ui-bg_glass_75_d0e5f5_1x400.png +0 -0
- data/vendor/assets/images/jquery-ui/ui-bg_glass_85_dfeffc_1x400.png +0 -0
- data/vendor/assets/images/jquery-ui/ui-bg_glass_95_fef1ec_1x400.png +0 -0
- data/vendor/assets/images/jquery-ui/ui-bg_gloss-wave_55_5c9ccc_500x100.png +0 -0
- data/vendor/assets/images/jquery-ui/ui-bg_inset-hard_100_f5f8f9_1x100.png +0 -0
- data/vendor/assets/images/jquery-ui/ui-bg_inset-hard_100_fcfdfd_1x100.png +0 -0
- data/vendor/assets/images/jquery-ui/ui-icons_217bc0_256x240.png +0 -0
- data/vendor/assets/images/jquery-ui/ui-icons_2e83ff_256x240.png +0 -0
- data/vendor/assets/images/jquery-ui/ui-icons_469bdd_256x240.png +0 -0
- data/vendor/assets/images/jquery-ui/ui-icons_6da8d5_256x240.png +0 -0
- data/vendor/assets/images/jquery-ui/ui-icons_cd0a0a_256x240.png +0 -0
- data/vendor/assets/images/jquery-ui/ui-icons_d8e7f3_256x240.png +0 -0
- data/vendor/assets/images/jquery-ui/ui-icons_f9bd01_256x240.png +0 -0
- data/vendor/assets/javascripts/json2.js +0 -487
@@ -25,4 +25,16 @@ class Collection::Member::Base < ActiveRecord::Base
|
|
25
25
|
belongs_to :collection, :class_name => 'Collection::Base'
|
26
26
|
belongs_to :target, :class_name => 'Concept::Base'
|
27
27
|
|
28
|
+
def self.view_section(obj)
|
29
|
+
"main"
|
30
|
+
end
|
31
|
+
|
32
|
+
def self.view_section_sort_key(obj)
|
33
|
+
100
|
34
|
+
end
|
35
|
+
|
36
|
+
def self.partial_name(obj)
|
37
|
+
"partials/collection/member"
|
38
|
+
end
|
39
|
+
|
28
40
|
end
|
@@ -16,22 +16,23 @@
|
|
16
16
|
|
17
17
|
class Collection::Member::SKOS::Base < Collection::Member::Base
|
18
18
|
|
19
|
-
self.rdf_namespace =
|
20
|
-
self.rdf_predicate =
|
19
|
+
self.rdf_namespace = 'skos'
|
20
|
+
self.rdf_predicate = 'member'
|
21
21
|
|
22
|
-
def self.build_from_rdf(
|
23
|
-
raise "
|
24
|
-
raise "
|
22
|
+
def self.build_from_rdf(rdf_subject, rdf_predicate, rdf_object)
|
23
|
+
raise "#{self.name}#build_from_rdf: Subject (#{rdf_subject}) must be a Collection." unless rdf_subject.is_a?(Collection::Base)
|
24
|
+
raise "#{self.name}#build_from_rdf: Object (#{rdf_object}) must be a Collection or Concept." unless rdf_object.is_a?(Collection::Base) or rdf_object.is_a?(Concept::Base)
|
25
25
|
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
26
|
+
member_instance = rdf_subject.members.select{|rel| rel.target == rdf_object}.first
|
27
|
+
if member_instance.nil?
|
28
|
+
predicate_class = Iqvoc::RDFAPI::PREDICATE_DICTIONARY[rdf_predicate] || self
|
29
|
+
member_instance = predicate_class.new(:target => rdf_object)
|
30
|
+
rdf_subject.members << member_instance
|
31
31
|
end
|
32
32
|
|
33
|
-
if
|
34
|
-
|
33
|
+
if rdf_object.collections.select{|coll| coll.id == rdf_subject.id}.empty?
|
34
|
+
rdf_object.collections << rdf_subject
|
35
35
|
end
|
36
|
+
member_instance
|
36
37
|
end
|
37
38
|
end
|
@@ -19,7 +19,7 @@ class Collection::SKOS::Base < Collection::Base
|
|
19
19
|
self.rdf_namespace = "skos"
|
20
20
|
self.rdf_class = "Collection"
|
21
21
|
|
22
|
-
def build_rdf_subject(
|
22
|
+
def build_rdf_subject(&block)
|
23
23
|
ns = IqRdf::Namespace.find_namespace_class(self.rdf_namespace)
|
24
24
|
raise "Namespace '#{base_namespace}' is not defined in IqRdf document." unless ns
|
25
25
|
subject = IqRdf.build_uri(self.origin, ns.build_uri(self.rdf_class), &block)
|
@@ -14,20 +14,5 @@
|
|
14
14
|
# See the License for the specific language governing permissions and
|
15
15
|
# limitations under the License.
|
16
16
|
|
17
|
-
class Collection::
|
18
|
-
|
19
|
-
belongs_to :subcollection, :class_name => 'Collection::Base', :foreign_key => 'target_id'
|
20
|
-
|
21
|
-
def self.view_section(obj)
|
22
|
-
"main"
|
23
|
-
end
|
24
|
-
|
25
|
-
def self.view_section_sort_key(obj)
|
26
|
-
100
|
27
|
-
end
|
28
|
-
|
29
|
-
def self.partial_name(obj)
|
30
|
-
"partials/collection/member"
|
31
|
-
end
|
32
|
-
|
17
|
+
class Collection::SKOS::Unordered < Collection::SKOS::Base
|
33
18
|
end
|
@@ -14,5 +14,12 @@
|
|
14
14
|
# See the License for the specific language governing permissions and
|
15
15
|
# limitations under the License.
|
16
16
|
|
17
|
+
|
17
18
|
class Collection::Unordered < Collection::SKOS::Base
|
19
|
+
|
20
|
+
def initialize(*args)
|
21
|
+
ActiveSupport::Deprecation.warn("Collection::Unordered is deprecated. Use Collection::SKOS::Unordered instead.")
|
22
|
+
super
|
23
|
+
end
|
24
|
+
|
18
25
|
end
|
data/app/models/concept/base.rb
CHANGED
@@ -27,19 +27,7 @@ class Concept::Base < ActiveRecord::Base
|
|
27
27
|
self.rdf_namespace = nil
|
28
28
|
self.rdf_class = nil
|
29
29
|
|
30
|
-
|
31
|
-
|
32
|
-
validates :origin, :presence => true, :on => :update
|
33
|
-
|
34
|
-
validate :ensure_distinct_versions, :on => :create
|
35
|
-
|
36
|
-
validate :ensure_a_pref_label_in_the_primary_thesaurus_language,
|
37
|
-
:on => :update
|
38
|
-
|
39
|
-
validate :ensure_no_pref_labels_share_the_same_language
|
40
|
-
validate :ensure_exclusive_top_term
|
41
|
-
validate :ensure_rooted_top_terms
|
42
|
-
validate :ensure_valid_rank_for_ranked_relations
|
30
|
+
include Concept::Validations
|
43
31
|
|
44
32
|
Iqvoc::Concept.include_modules.each do |mod|
|
45
33
|
include mod
|
@@ -63,9 +51,10 @@ class Concept::Base < ActiveRecord::Base
|
|
63
51
|
labeling_class = reflection && reflection.class_name && reflection.class_name.constantize
|
64
52
|
if labeling_class && labeling_class < Labeling::Base
|
65
53
|
self.send(relation_name).all.map(&:destroy)
|
66
|
-
lang_values = {nil => lang_values.first} if lang_values.is_a?(Array) # For language = nil: <input name=bla[labeling_class][]> => Results in an Array!
|
67
|
-
lang_values.each do |lang,
|
68
|
-
|
54
|
+
lang_values = { nil => lang_values.first } if lang_values.is_a?(Array) # For language = nil: <input name=bla[labeling_class][]> => Results in an Array! -- XXX: obsolete/dupe (cf `labelings_by_text=`)?
|
55
|
+
lang_values.each do |lang, inline_values|
|
56
|
+
lang = nil if lang.to_s == 'none'
|
57
|
+
Iqvoc::InlineDataHelper.parse_inline_values(inline_values).each do |value|
|
69
58
|
value.squish!
|
70
59
|
self.send(relation_name).build(:target => labeling_class.label_class.new(:value => value, :language => lang)) unless value.blank?
|
71
60
|
end
|
@@ -85,7 +74,7 @@ class Concept::Base < ActiveRecord::Base
|
|
85
74
|
# rankable: {'relation_name' => ['origin1:100', 'origin2:90']}
|
86
75
|
(@concept_relations_by_id ||= {}).each do |relation_name, new_origins|
|
87
76
|
# Split comma-separated origins and clean up parameter strings
|
88
|
-
new_origins = new_origins.split(Iqvoc::InlineDataHelper::
|
77
|
+
new_origins = new_origins.split(Iqvoc::InlineDataHelper::SPLITTER).map(&:squish)
|
89
78
|
|
90
79
|
# Extract embedded ranks (if any) from origin strings (e.g. "origin1:100")
|
91
80
|
# => { 'origin1' => nil, 'origin2' => 90 }
|
@@ -139,7 +128,7 @@ class Concept::Base < ActiveRecord::Base
|
|
139
128
|
has_many :matches, :foreign_key => 'concept_id', :class_name => "Match::Base", :dependent => :destroy
|
140
129
|
include_to_deep_cloning(:matches)
|
141
130
|
|
142
|
-
has_many :collection_members, :foreign_key => 'target_id', :class_name => "Collection::Member::
|
131
|
+
has_many :collection_members, :foreign_key => 'target_id', :class_name => "Collection::Member::Base", :dependent => :destroy
|
143
132
|
has_many :collections, :through => :collection_members, :class_name => Iqvoc::Collection.base_class_name
|
144
133
|
include_to_deep_cloning(:collection_members)
|
145
134
|
|
@@ -300,18 +289,22 @@ class Concept::Base < ActiveRecord::Base
|
|
300
289
|
def labelings_by_text=(hash)
|
301
290
|
@labelings_by_text = hash
|
302
291
|
|
303
|
-
|
304
|
-
|
305
|
-
|
292
|
+
@labelings_by_text.each do |relation_name, labels_by_lang|
|
293
|
+
# if `language` is `nil`, the respective HTML form field returns an array
|
294
|
+
# instead of a hash (`<input name=bla[labeling_class][]>`)
|
295
|
+
if labels_by_lang.is_a?(Array)
|
296
|
+
@labelings_by_text[relation_name] = { nil => labels_by_lang.first }
|
297
|
+
end
|
306
298
|
end
|
307
299
|
|
308
300
|
@labelings_by_text
|
309
301
|
end
|
310
302
|
|
311
303
|
def labelings_by_text(relation_name, language)
|
312
|
-
(@labelings_by_text && @labelings_by_text[relation_name] &&
|
313
|
-
|
314
|
-
|
304
|
+
(@labelings_by_text && @labelings_by_text[relation_name] &&
|
305
|
+
@labelings_by_text[relation_name][language]) ||
|
306
|
+
Iqvoc::InlineDataHelper.generate_inline_values(self.send(relation_name).
|
307
|
+
by_label_language(language).map { |l| l.target.value })
|
315
308
|
end
|
316
309
|
|
317
310
|
def concept_relations_by_id=(hash)
|
@@ -321,7 +314,7 @@ class Concept::Base < ActiveRecord::Base
|
|
321
314
|
def concept_relations_by_id(relation_name)
|
322
315
|
(@concept_relations_by_id && @concept_relations_by_id[relation_name]) ||
|
323
316
|
self.send(relation_name).map { |l| l.target.origin }.
|
324
|
-
join(Iqvoc::InlineDataHelper::
|
317
|
+
join(Iqvoc::InlineDataHelper::JOINER)
|
325
318
|
end
|
326
319
|
|
327
320
|
def concept_relations_by_id_and_rank(relation_name)
|
@@ -335,12 +328,12 @@ class Concept::Base < ActiveRecord::Base
|
|
335
328
|
# If no prefLabel for the requested language exists, a new label will be returned
|
336
329
|
# (if you modify it, don't forget to save it afterwards!)
|
337
330
|
def pref_label
|
338
|
-
lang = I18n.locale.to_s
|
331
|
+
lang = I18n.locale.to_s == "none" ? nil : I18n.locale.to_s
|
339
332
|
@cached_pref_labels ||= pref_labels.each_with_object({}) do |label, hash|
|
340
333
|
if hash[label.language]
|
341
334
|
Rails.logger.warn("Two pref_labels (#{hash[label.language]}, #{label}) for one language (#{label.language}). Taking the second one.")
|
342
335
|
end
|
343
|
-
hash[label.language
|
336
|
+
hash[label.language] = label
|
344
337
|
end
|
345
338
|
if @cached_pref_labels[lang].nil?
|
346
339
|
# Fallback to the main language
|
@@ -354,12 +347,16 @@ class Concept::Base < ActiveRecord::Base
|
|
354
347
|
def labels_for_labeling_class_and_language(labeling_class, lang = :en, only_published = true)
|
355
348
|
# Convert lang to string in case it's not nil.
|
356
349
|
# nil values play their own role for labels without a language.
|
357
|
-
|
350
|
+
if lang == "none"
|
351
|
+
lang = nil
|
352
|
+
elsif lang
|
353
|
+
lang = lang.to_s
|
354
|
+
end
|
358
355
|
labeling_class = labeling_class.name if labeling_class < ActiveRecord::Base # Use the class name string
|
359
356
|
@labels ||= labelings.each_with_object({}) do |labeling, hash|
|
360
357
|
((hash[labeling.class.name.to_s] ||= {})[labeling.target.language] ||= []) << labeling.target if labeling.target
|
361
358
|
end
|
362
|
-
|
359
|
+
((@labels && @labels[labeling_class] && @labels[labeling_class][lang]) || []).select{|l| l.published? || !only_published}
|
363
360
|
end
|
364
361
|
|
365
362
|
def related_concepts_for_relation_class(relation_class, only_published = true)
|
@@ -416,82 +413,4 @@ class Concept::Base < ActiveRecord::Base
|
|
416
413
|
}
|
417
414
|
end
|
418
415
|
|
419
|
-
# ********** Validation methods
|
420
|
-
|
421
|
-
# validates that
|
422
|
-
# a) no more than one concept with the same origin already exists
|
423
|
-
# b) if a concept with the same origin exists, its publication state differs
|
424
|
-
# from the to-be-saved one's
|
425
|
-
def ensure_distinct_versions
|
426
|
-
query = Concept::Base.by_origin(origin)
|
427
|
-
existing_total = query.count
|
428
|
-
if existing_total >= 2
|
429
|
-
errors.add :base, I18n.t("txt.models.concept.version_error")
|
430
|
-
elsif existing_total == 1
|
431
|
-
unless (query.published.count == 0 and published?) or
|
432
|
-
(query.published.count == 1 and not published?)
|
433
|
-
errors.add :base, I18n.t("txt.models.concept.version_error")
|
434
|
-
end
|
435
|
-
end
|
436
|
-
end
|
437
|
-
|
438
|
-
# top term and broader relations are mutually exclusive
|
439
|
-
def ensure_exclusive_top_term
|
440
|
-
if @full_validation
|
441
|
-
if top_term && broader_relations.any?
|
442
|
-
errors.add :base, I18n.t("txt.models.concept.top_term_exclusive_error")
|
443
|
-
end
|
444
|
-
end
|
445
|
-
end
|
446
|
-
|
447
|
-
# top terms must never be used as descendants (narrower relation targets)
|
448
|
-
# NB: for top terms themselves, this is covered by `ensure_exclusive_top_term`
|
449
|
-
def ensure_rooted_top_terms
|
450
|
-
if @full_validation
|
451
|
-
if narrower_relations.includes(:target). # XXX: inefficient?
|
452
|
-
select { |rel| rel.target && rel.target.top_term? }.any?
|
453
|
-
errors.add :base, I18n.t("txt.models.concept.top_term_rooted_error")
|
454
|
-
end
|
455
|
-
end
|
456
|
-
end
|
457
|
-
|
458
|
-
def ensure_a_pref_label_in_the_primary_thesaurus_language
|
459
|
-
if @full_validation
|
460
|
-
labels = pref_labels.select{|l| l.published?}
|
461
|
-
if labels.count == 0
|
462
|
-
errors.add :base, I18n.t("txt.models.concept.no_pref_label_error")
|
463
|
-
elsif not labels.map(&:language).map(&:to_s).include?(Iqvoc::Concept.pref_labeling_languages.first.to_s)
|
464
|
-
errors.add :base, I18n.t("txt.models.concept.main_pref_label_language_missing_error")
|
465
|
-
end
|
466
|
-
end
|
467
|
-
end
|
468
|
-
|
469
|
-
def ensure_no_pref_labels_share_the_same_language
|
470
|
-
# We have many sources a prefLabel can be defined in
|
471
|
-
pls = pref_labelings.map(&:target) +
|
472
|
-
send(Iqvoc::Concept.pref_labeling_class_name.to_relation_name).map(&:target) +
|
473
|
-
labelings.select{|l| l.is_a?(Iqvoc::Concept.pref_labeling_class)}.map(&:target)
|
474
|
-
languages = {}
|
475
|
-
pls.compact.each do |pref_label|
|
476
|
-
lang = pref_label.language.to_s
|
477
|
-
origin = (pref_label.origin || pref_label.id || pref_label.value).to_s
|
478
|
-
if (languages.keys.include?(lang) && languages[lang] != origin)
|
479
|
-
errors.add :pref_labelings, I18n.t("txt.models.concept.pref_labels_with_same_languages_error")
|
480
|
-
end
|
481
|
-
languages[lang] = origin
|
482
|
-
end
|
483
|
-
end
|
484
|
-
|
485
|
-
def ensure_valid_rank_for_ranked_relations
|
486
|
-
if @full_validation
|
487
|
-
relations.each do |relation|
|
488
|
-
if relation.class.rankable? && !(0..100).include?(relation.rank)
|
489
|
-
errors.add :base, I18n.t("txt.models.concept.invalid_rank_for_ranked_relations",
|
490
|
-
:relation => relation.class.model_name.human.downcase,
|
491
|
-
:relation_target_label => relation.target.pref_label.to_s)
|
492
|
-
end
|
493
|
-
end
|
494
|
-
end
|
495
|
-
end
|
496
|
-
|
497
416
|
end
|
@@ -18,15 +18,25 @@ class Concept::Relation::SKOS::Base < Concept::Relation::Base
|
|
18
18
|
|
19
19
|
self.rdf_namespace = 'skos'
|
20
20
|
|
21
|
-
def self.build_from_rdf(
|
22
|
-
raise "
|
23
|
-
raise "
|
21
|
+
def self.build_from_rdf(rdf_subject, rdf_predicate, rdf_object)
|
22
|
+
raise "#{self.name}#build_from_rdf: Subject (#{rdf_subject}) must be a Concept." unless rdf_subject.is_a? Concept::Base
|
23
|
+
raise "#{self.name}#build_from_rdf: Object (#{rdf_object}) must be a Concept." unless rdf_object.is_a? Concept::Base
|
24
24
|
|
25
|
-
|
26
|
-
|
25
|
+
relation_class = Iqvoc::RDFAPI::PREDICATE_DICTIONARY[rdf_predicate] || self
|
26
|
+
|
27
|
+
relation_instance = rdf_subject.send(self.name.to_relation_name).select{|rel| rel.target == rdf_object}
|
28
|
+
unless relation_instance
|
29
|
+
relation_instance = relation_class.new(:target => rdf_object)
|
30
|
+
rdf_subject.send(self.name.to_relation_name) << relation_instance
|
27
31
|
end
|
28
|
-
|
29
|
-
|
32
|
+
|
33
|
+
if relation_class.bidirectional?
|
34
|
+
reverse_class = relation_class.reverse_relation_class
|
35
|
+
reverse_collection = rdf_object.send(reverse_class.name.to_relation_name)
|
36
|
+
if reverse_collection.select{|rel| rel.target == rdf_subject}.empty?
|
37
|
+
reverse_instance = reverse_class.new(:target => rdf_subject)
|
38
|
+
reverse_collection << reverse_instance
|
39
|
+
end
|
30
40
|
end
|
31
41
|
end
|
32
42
|
|
@@ -19,7 +19,7 @@ class Concept::SKOS::Base < Concept::Base
|
|
19
19
|
self.rdf_namespace = "skos"
|
20
20
|
self.rdf_class = "Concept"
|
21
21
|
|
22
|
-
def build_rdf_subject(
|
22
|
+
def build_rdf_subject(&block)
|
23
23
|
ns = IqRdf::Namespace.find_namespace_class(self.rdf_namespace)
|
24
24
|
raise "Namespace '#{self.rdf_namespace}' is not defined in IqRdf document." unless ns
|
25
25
|
subject = IqRdf.build_uri(self.origin, ns.build_uri(self.rdf_class), &block)
|
@@ -32,4 +32,13 @@ class Concept::SKOS::Base < Concept::Base
|
|
32
32
|
return subject
|
33
33
|
end
|
34
34
|
|
35
|
+
# ********** Scopes
|
36
|
+
def self.expired(time = Time.now)
|
37
|
+
where(arel_table[:expired_at].lt(time))
|
38
|
+
end
|
39
|
+
|
40
|
+
def self.not_expired(time = Time.now)
|
41
|
+
col = arel_table[:expired_at]
|
42
|
+
where((col.eq(nil)).or(col.gteq(time)))
|
43
|
+
end
|
35
44
|
end
|
@@ -37,7 +37,7 @@ class Concept::SKOS::Scheme
|
|
37
37
|
:scheme
|
38
38
|
end
|
39
39
|
|
40
|
-
def build_rdf_subject(
|
40
|
+
def build_rdf_subject(&block)
|
41
41
|
ns = IqRdf::Namespace.find_namespace_class(self.class.rdf_namespace.to_sym)
|
42
42
|
raise "Namespace '#{rdf_namespace}' is not defined in IqRdf document." unless ns
|
43
43
|
IqRdf.build_uri(origin, ns.build_uri(self.class.rdf_class), &block)
|
@@ -0,0 +1,117 @@
|
|
1
|
+
module Concept
|
2
|
+
module Validations
|
3
|
+
extend ActiveSupport::Concern
|
4
|
+
|
5
|
+
included do
|
6
|
+
validates :origin, :presence => true, :on => :update
|
7
|
+
|
8
|
+
validate :distinct_versions, :on => :create
|
9
|
+
validate :pref_label_in_primary_thesaurus_language, :on => :update
|
10
|
+
validate :unique_pref_label_language
|
11
|
+
validate :exclusive_top_term
|
12
|
+
validate :rooted_top_terms
|
13
|
+
validate :valid_rank_for_ranked_relations
|
14
|
+
validate :unique_pref_label
|
15
|
+
end
|
16
|
+
|
17
|
+
def distinct_versions
|
18
|
+
query = Concept::Base.by_origin(origin)
|
19
|
+
existing_total = query.count
|
20
|
+
if existing_total >= 2
|
21
|
+
errors.add :base, I18n.t("txt.models.concept.version_error")
|
22
|
+
elsif existing_total == 1
|
23
|
+
unless (query.published.count == 0 and published?) or
|
24
|
+
(query.published.count == 1 and not published?)
|
25
|
+
errors.add :base, I18n.t("txt.models.concept.version_error")
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
# top term and broader relations are mutually exclusive
|
31
|
+
def exclusive_top_term
|
32
|
+
if @full_validation
|
33
|
+
if top_term && broader_relations.any?
|
34
|
+
errors.add :base, I18n.t("txt.models.concept.top_term_exclusive_error")
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
# top terms must never be used as descendants (narrower relation targets)
|
40
|
+
# NB: for top terms themselves, this is covered by `ensure_exclusive_top_term`
|
41
|
+
def rooted_top_terms
|
42
|
+
if @full_validation
|
43
|
+
if narrower_relations.includes(:target). # XXX: inefficient?
|
44
|
+
select { |rel| rel.target && rel.target.top_term? }.any?
|
45
|
+
errors.add :base, I18n.t("txt.models.concept.top_term_rooted_error")
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
def pref_label_in_primary_thesaurus_language
|
51
|
+
if @full_validation
|
52
|
+
labels = pref_labels.select{|l| l.published?}
|
53
|
+
if labels.count == 0
|
54
|
+
errors.add :base, I18n.t("txt.models.concept.no_pref_label_error")
|
55
|
+
elsif not labels.map(&:language).map(&:to_s).include?(Iqvoc::Concept.pref_labeling_languages.first.to_s)
|
56
|
+
errors.add :base, I18n.t("txt.models.concept.main_pref_label_language_missing_error")
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
def unique_pref_label_language
|
62
|
+
# We have many sources a prefLabel can be defined in
|
63
|
+
pls = pref_labelings.map(&:target) +
|
64
|
+
send(Iqvoc::Concept.pref_labeling_class_name.to_relation_name).map(&:target) +
|
65
|
+
labelings.select{|l| l.is_a?(Iqvoc::Concept.pref_labeling_class)}.map(&:target)
|
66
|
+
languages = {}
|
67
|
+
pls.compact.each do |pref_label|
|
68
|
+
lang = pref_label.language.to_s
|
69
|
+
origin = (pref_label.origin || pref_label.id || pref_label.value).to_s
|
70
|
+
if (languages.keys.include?(lang) && languages[lang] != origin)
|
71
|
+
errors.add :pref_labelings, I18n.t("txt.models.concept.pref_labels_with_same_languages_error")
|
72
|
+
end
|
73
|
+
languages[lang] = origin
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
def unique_pref_label
|
78
|
+
if @full_validation
|
79
|
+
# checks if there are any existing pref labels with the same
|
80
|
+
# language and value
|
81
|
+
conflicting_pref_labels = pref_labels.select do |l|
|
82
|
+
Labeling::SKOS::PrefLabel.
|
83
|
+
joins(:owner, :target).
|
84
|
+
where(:labels => { :value => l.value, :language => l.language }).
|
85
|
+
where("labelings.owner_id != ?", id).
|
86
|
+
where("concepts.origin != ?", origin).
|
87
|
+
any?
|
88
|
+
end
|
89
|
+
|
90
|
+
if conflicting_pref_labels.any?
|
91
|
+
if conflicting_pref_labels.one?
|
92
|
+
errors.add :base,
|
93
|
+
I18n.t("txt.models.concept.pref_label_not_unique",
|
94
|
+
:label => conflicting_pref_labels.last.value)
|
95
|
+
else
|
96
|
+
errors.add :base,
|
97
|
+
I18n.t("txt.models.concept.pref_labels_not_unique",
|
98
|
+
:label => conflicting_pref_labels.map(&:value).join(", "))
|
99
|
+
end
|
100
|
+
end
|
101
|
+
end
|
102
|
+
end
|
103
|
+
|
104
|
+
def valid_rank_for_ranked_relations
|
105
|
+
if @full_validation
|
106
|
+
relations.each do |relation|
|
107
|
+
if relation.class.rankable? && !(0..100).include?(relation.rank)
|
108
|
+
errors.add :base, I18n.t("txt.models.concept.invalid_rank_for_ranked_relations",
|
109
|
+
:relation => relation.class.model_name.human.downcase,
|
110
|
+
:relation_target_label => relation.target.pref_label.to_s)
|
111
|
+
end
|
112
|
+
end
|
113
|
+
end
|
114
|
+
end
|
115
|
+
|
116
|
+
end
|
117
|
+
end
|
data/app/models/label/base.rb
CHANGED
@@ -33,7 +33,8 @@ class Label::Base < ActiveRecord::Base
|
|
33
33
|
# ********* Scopes
|
34
34
|
|
35
35
|
def self.by_language(lang_code)
|
36
|
-
if
|
36
|
+
lang_code = nil if lang_code.to_s == "none"
|
37
|
+
if (lang_code.is_a?(Array) && lang_code.include?("none"))
|
37
38
|
where(arel_table[:language].eq(nil).or(arel_table[:language].in(lang_code.compact)))
|
38
39
|
elsif lang_code.blank?
|
39
40
|
where(arel_table[:language].eq(nil))
|
@@ -93,8 +94,8 @@ class Label::Base < ActiveRecord::Base
|
|
93
94
|
end
|
94
95
|
|
95
96
|
def to_s
|
96
|
-
if language.
|
97
|
-
value.to_s + " [#{I18n.t("txt.common.translation_missing_for")} '#{I18n.locale
|
97
|
+
if (language.presence || "none") != I18n.locale.to_s
|
98
|
+
value.to_s + " [#{I18n.t("txt.common.translation_missing_for")} '#{I18n.locale}']"
|
98
99
|
else
|
99
100
|
value.to_s
|
100
101
|
end
|
@@ -28,6 +28,14 @@ class Labeling::SKOS::Base < Labeling::Base
|
|
28
28
|
includes(:target).merge(self.label_class.where(:value => label, :language => language))
|
29
29
|
end
|
30
30
|
|
31
|
+
def self.concept_expired
|
32
|
+
includes(:owner).merge(Iqvoc::Concept.base_class.expired)
|
33
|
+
end
|
34
|
+
|
35
|
+
def self.concept_not_expired
|
36
|
+
includes(:owner).merge(Iqvoc::Concept.base_class.not_expired)
|
37
|
+
end
|
38
|
+
|
31
39
|
# ********** Methods
|
32
40
|
|
33
41
|
def self.label_class
|
@@ -35,11 +43,11 @@ class Labeling::SKOS::Base < Labeling::Base
|
|
35
43
|
end
|
36
44
|
|
37
45
|
def self.partial_name(obj)
|
38
|
-
|
46
|
+
'partials/labeling/skos/base'
|
39
47
|
end
|
40
48
|
|
41
49
|
def self.edit_partial_name(obj)
|
42
|
-
|
50
|
+
'partials/labeling/skos/edit_base'
|
43
51
|
end
|
44
52
|
|
45
53
|
def self.single_query(params = {})
|
@@ -54,10 +62,10 @@ class Labeling::SKOS::Base < Labeling::Base
|
|
54
62
|
end
|
55
63
|
|
56
64
|
if params[:collection_origin].present?
|
57
|
-
collection = Collection::
|
65
|
+
collection = Collection::Base.where(:origin => params[:collection_origin]).last
|
58
66
|
if collection
|
59
67
|
scope = scope.includes(:owner => :collection_members)
|
60
|
-
scope = scope.where("#{Collection::Member::Base.table_name}.collection_id" => collection)
|
68
|
+
scope = scope.where("#{Collection::Member::Base.table_name}.collection_id" => collection.id)
|
61
69
|
else
|
62
70
|
raise "Collection with Origin #{params[:collection_origin]} not found!"
|
63
71
|
end
|
@@ -65,10 +73,10 @@ class Labeling::SKOS::Base < Labeling::Base
|
|
65
73
|
scope = scope.includes(:owner)
|
66
74
|
|
67
75
|
scope = case params[:for]
|
68
|
-
when
|
69
|
-
scope.where(
|
70
|
-
when
|
71
|
-
scope.where(
|
76
|
+
when 'concept'
|
77
|
+
scope.where('concepts.type' => Iqvoc::Concept.base_class_name).merge(Concept::Base.published)
|
78
|
+
when 'collection'
|
79
|
+
scope.where('concepts.type' => Iqvoc::Collection.base_class_name)
|
72
80
|
else
|
73
81
|
# no additional conditions
|
74
82
|
scope
|
@@ -81,18 +89,21 @@ class Labeling::SKOS::Base < Labeling::Base
|
|
81
89
|
'partials/labeling/skos/search_result'
|
82
90
|
end
|
83
91
|
|
84
|
-
def self.build_from_rdf(
|
85
|
-
raise "
|
86
|
-
raise "
|
92
|
+
def self.build_from_rdf(rdf_subject, rdf_predicate, rdf_object)
|
93
|
+
raise "#{self.name}#build_from_rdf: Subject (#{rdf_subject}) must be a Concept." unless rdf_subject.is_a?(Concept::Base)
|
94
|
+
raise "#{self.name}#build_from_rdf: Object (#{rdf_object}) must be a string literal" unless rdf_object =~ /^"(.+)"(@(.+))?$/
|
87
95
|
|
88
96
|
lang = $3
|
89
97
|
value = JSON.parse(%Q{["#{$1}"]})[0].gsub("\\n", "\n") # Trick to decode \uHHHHH chars
|
90
98
|
|
91
|
-
|
99
|
+
predicate_class = Iqvoc::RDFAPI::PREDICATE_DICTIONARY[rdf_predicate] || self
|
100
|
+
predicate_class.new(:target => self.label_class.new(:value => value, :language => lang)).tap do |labeling|
|
101
|
+
rdf_subject.send(predicate_class.name.to_relation_name) << labeling
|
102
|
+
end
|
92
103
|
end
|
93
104
|
|
94
105
|
def build_rdf(document, subject)
|
95
|
-
subject.send(self.rdf_namespace.camelcase).send(self.rdf_predicate, target.to_s, :lang => target.language)
|
106
|
+
subject.send(self.rdf_namespace.camelcase).send(self.rdf_predicate, target.value.to_s, :lang => target.language)
|
96
107
|
end
|
97
108
|
|
98
109
|
def build_search_result_rdf(document, result)
|
@@ -1,13 +1,32 @@
|
|
1
|
+
# encoding: UTF-8
|
2
|
+
|
3
|
+
# Copyright 2011 innoQ Deutschland GmbH
|
4
|
+
#
|
5
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
6
|
+
# you may not use this file except in compliance with the License.
|
7
|
+
# You may obtain a copy of the License at
|
8
|
+
#
|
9
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
10
|
+
#
|
11
|
+
# Unless required by applicable law or agreed to in writing, software
|
12
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
13
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
14
|
+
# See the License for the specific language governing permissions and
|
15
|
+
# limitations under the License.
|
16
|
+
|
1
17
|
class Match::SKOS::Base < Match::Base
|
2
18
|
|
3
19
|
self.rdf_namespace = 'skos'
|
4
20
|
|
5
|
-
def self.build_from_rdf(
|
6
|
-
raise "
|
7
|
-
raise "
|
21
|
+
def self.build_from_rdf(rdf_subject, rdf_predicate, rdf_object)
|
22
|
+
raise "#{self.class}#build_from_rdf: Subject (#{rdf_subject}) must be able to recieve this kind of match (#{self.name} => #{self.name.to_relation_name})." unless rdf_subject.class.reflections.include?(self.name.to_relation_name)
|
23
|
+
raise "#{self.class}#build_from_rdf: Object (#{rdf_object}) must be a URI" unless rdf_object =~ /^<(.+)>$/ # XXX: this assumes nt-format, right?
|
8
24
|
uri = $1
|
9
25
|
|
10
|
-
|
26
|
+
match_class = Iqvoc::RDFAPI::PREDICATE_DICTIONARY[rdf_predicate] || self
|
27
|
+
match_class.new(:value => uri).tap do |match|
|
28
|
+
rdf_subject.send(self.name.to_relation_name) << match
|
29
|
+
end
|
11
30
|
end
|
12
31
|
|
13
32
|
def build_rdf(document, subject)
|
@@ -16,7 +35,7 @@ class Match::SKOS::Base < Match::Base
|
|
16
35
|
if (IqRdf::Namespace.find_namespace_class(self.rdf_namespace.camelcase))
|
17
36
|
subject.send(self.rdf_namespace.camelcase).send(self.rdf_predicate, URI.parse(value))
|
18
37
|
else
|
19
|
-
raise "
|
38
|
+
raise "#{self.class}#build_rdf: couldn't find Namespace '#{self.rdf_namespace.camelcase}'."
|
20
39
|
end
|
21
40
|
end
|
22
41
|
|