iqvoc 4.0.8 → 4.0.9
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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
|
|