iqvoc_skosxl 1.1.4

Sign up to get free protection for your applications and to get access to all the features.
Files changed (78) hide show
  1. data/Gemfile +40 -0
  2. data/Gemfile.lock +154 -0
  3. data/README.md +26 -0
  4. data/Rakefile +11 -0
  5. data/app/assets/javascripts/iqvoc_skosxl/manifest.js +0 -0
  6. data/app/assets/javascripts/manifest.js +3 -0
  7. data/app/assets/stylesheets/iqvoc_skosxl/manifest.css +0 -0
  8. data/app/assets/stylesheets/manifest.css +5 -0
  9. data/app/controllers/labels/versions_controller.rb +109 -0
  10. data/app/controllers/labels_controller.rb +130 -0
  11. data/app/controllers/rdf_controller.rb +23 -0
  12. data/app/helpers/iqvoc_skosxl_helper.rb +18 -0
  13. data/app/helpers/labels_helper.rb +68 -0
  14. data/app/models/concept/skosxl/extension.rb +62 -0
  15. data/app/models/label/relation/base.rb +54 -0
  16. data/app/models/label/relation/skosxl/base.rb +12 -0
  17. data/app/models/label/skosxl/base.rb +219 -0
  18. data/app/models/labeling/skosxl/alt_label.rb +8 -0
  19. data/app/models/labeling/skosxl/base.rb +75 -0
  20. data/app/models/labeling/skosxl/hidden_label.rb +12 -0
  21. data/app/models/labeling/skosxl/pref_label.rb +12 -0
  22. data/app/views/labels/_base_data.html.erb +62 -0
  23. data/app/views/labels/_change_note.html.erb +46 -0
  24. data/app/views/labels/_details.html.erb +6 -0
  25. data/app/views/labels/_label_relation.html.erb +7 -0
  26. data/app/views/labels/_labeling.html.erb +3 -0
  27. data/app/views/labels/_note.html.erb +33 -0
  28. data/app/views/labels/_show_head.html.erb +22 -0
  29. data/app/views/labels/_value_and_language.html.erb +9 -0
  30. data/app/views/labels/edit.html.erb +22 -0
  31. data/app/views/labels/new.html.erb +3 -0
  32. data/app/views/labels/show.ttl.erb +1 -0
  33. data/app/views/labels/show_published.html.erb +13 -0
  34. data/app/views/labels/show_unpublished.html.erb +36 -0
  35. data/app/views/partials/label/relation/_base.html.erb +9 -0
  36. data/app/views/partials/label/relation/_edit_base.html.erb +13 -0
  37. data/app/views/partials/label/skosxl/_edit_link_base.html.erb +1 -0
  38. data/app/views/partials/label/skosxl/_new_link_base.html.erb +7 -0
  39. data/app/views/partials/labeling/skosxl/_base.html.erb +19 -0
  40. data/app/views/partials/labeling/skosxl/_edit_base.html.erb +15 -0
  41. data/app/views/partials/labeling/skosxl/_search_result.html.erb +9 -0
  42. data/app/views/rdf/show_label.iqrdf +5 -0
  43. data/config/application.rb +56 -0
  44. data/config/boot.rb +13 -0
  45. data/config/database.template.yml +38 -0
  46. data/config/database.yml +36 -0
  47. data/config/engine.rb +13 -0
  48. data/config/environment.rb +5 -0
  49. data/config/environments/development.rb +55 -0
  50. data/config/environments/production.rb +64 -0
  51. data/config/environments/test.rb +44 -0
  52. data/config/initializers/iqvoc.rb +4 -0
  53. data/config/initializers/iqvoc_skosxl.rb +1 -0
  54. data/config/initializers/secret_token.rb.template +9 -0
  55. data/config/initializers/session_store.rb +8 -0
  56. data/config/locales/activerecord.de.yml +18 -0
  57. data/config/locales/activerecord.en.yml +18 -0
  58. data/config/locales/de.yml +5 -0
  59. data/config/locales/en.yml +5 -0
  60. data/config/routes.rb +15 -0
  61. data/db/migrate/20110408121540_extend_label.rb +37 -0
  62. data/db/migrate/20110408123644_add_label_relations.rb +24 -0
  63. data/db/schema.rb +146 -0
  64. data/db/seeds.rb +0 -0
  65. data/iqvoc_skosxl.gemspec +22 -0
  66. data/lib/engine_tasks/db.rake +19 -0
  67. data/lib/iqvoc/skosxl/version.rb +5 -0
  68. data/lib/iqvoc/xllabel.rb +60 -0
  69. data/lib/iqvoc_skosxl.rb +22 -0
  70. data/test/factories.rb +23 -0
  71. data/test/integration/concept_label_language_test.rb +95 -0
  72. data/test/integration/dashboard_test.rb +29 -0
  73. data/test/integration/edit_labels_test.rb +26 -0
  74. data/test/integration/labels_order_test.rb +27 -0
  75. data/test/integration_test_helper.rb +27 -0
  76. data/test/test_helper.rb +15 -0
  77. data/test/unit/label_test.rb +30 -0
  78. metadata +154 -0
@@ -0,0 +1,23 @@
1
+ require_dependency Iqvoc::Engine.find_root_with_flag("app").join("app/controllers/rdf_controller").to_s
2
+ class RdfController
3
+
4
+ def show_with_labels
5
+ scope = params[:published] == "0" ? Iqvoc::XLLabel.base_class.scoped.unpublished : Iqvoc::XLLabel.base_class.scoped.published
6
+ if @label = scope.by_origin(params[:id]).with_associations.last
7
+ respond_to do |format|
8
+ format.html {
9
+ redirect_to label_url(:id => @label.origin, :published => params[:published])
10
+ }
11
+ format.any {
12
+ authorize! :read, @label
13
+ render "show_label"
14
+ }
15
+ end
16
+ else
17
+ show_without_labels
18
+ end
19
+ end
20
+
21
+ alias_method_chain(:show, :labels)
22
+
23
+ end
@@ -0,0 +1,18 @@
1
+ module IqvocSkosxlHelper
2
+
3
+ def iqvoc_skosxl_default_rdf_namespaces
4
+ {
5
+ }
6
+ end
7
+
8
+ def render_label(label)
9
+ if label.new_record?
10
+ "-"
11
+ elsif label.is_a?(Label::SKOSXL::Base)
12
+ link_to(label.to_s, label_path(:id => label))
13
+ else
14
+ label.to_s
15
+ end
16
+ end
17
+
18
+ end
@@ -0,0 +1,68 @@
1
+ module LabelsHelper
2
+
3
+ def render_label_rdf(document, label)
4
+ document << label.build_rdf_subject(document, controller) do |c|
5
+
6
+ c.Schema::expires(label.expired_at) if label.expired_at
7
+
8
+ c.Owl::deprecated(true) if label.expired_at and label.expired_at <= Date.new
9
+
10
+ c.Skosxl::literalForm(label.value, :lang => label.language)
11
+
12
+ label.relations.each do |relation|
13
+ relation.build_rdf(document, c)
14
+ end
15
+
16
+ label.notes.each do |note|
17
+ note.build_rdf(document, c)
18
+ end
19
+
20
+ Iqvoc::XLLabel.additional_association_class_names.keys.each do |class_name|
21
+ label.send(class_name.to_relation_name).each do |additional_object|
22
+ additional_object.build_rdf(document, c)
23
+ end
24
+ end
25
+
26
+ =begin
27
+ concept.matches.each do |match|
28
+ match.build_rdf(document, c)
29
+ end
30
+
31
+
32
+ =end
33
+ end
34
+ end
35
+
36
+ def render_label_association(hash, label, association_class, further_options = {})
37
+ return unless association_class.partial_name(label)
38
+ ((hash[association_class.view_section(label)] ||= {})[association_class.view_section_sort_key(label)] ||= "") <<
39
+ render(association_class.partial_name(label), further_options.merge(:label => label, :klass => association_class))
40
+ end
41
+
42
+ def label_view_data(label)
43
+ res = {'main' => {}}
44
+
45
+ res['main'][10] = render 'labels/value_and_language', :label => label
46
+
47
+ res['main'][1000] = render 'labels/details', :label => label
48
+
49
+ Iqvoc::Concept.labeling_classes.keys.each do |labeling_class|
50
+ render_label_association(res, label, labeling_class)
51
+ end
52
+
53
+ Iqvoc::XLLabel.relation_classes.each do |relation_class|
54
+ render_label_association(res, label, relation_class)
55
+ end
56
+
57
+ Iqvoc::XLLabel.note_classes.each do |note_class|
58
+ render_label_association(res, label, note_class)
59
+ end
60
+
61
+ Iqvoc::XLLabel.additional_association_classes.keys.each do |assoc_class|
62
+ render_label_association(res, label, assoc_class)
63
+ end
64
+
65
+ res
66
+ end
67
+
68
+ end
@@ -0,0 +1,62 @@
1
+ module Concept
2
+ module SKOSXL
3
+ module Extension
4
+
5
+ extend ActiveSupport::Concern
6
+
7
+ included do
8
+ validate :valid_label_language
9
+
10
+ after_save do |concept|
11
+ # Labelings
12
+ (@labelings_by_id ||= {}).each do |labeling_relation_name, origin_mappings|
13
+ # Remove all associated labelings of the given type
14
+ concept.send(labeling_relation_name).destroy_all
15
+
16
+ # (Re)create labelings reflecting a widget's parameters
17
+ origin_mappings.each do |language, new_origins|
18
+ new_origins = new_origins.
19
+ split(Iqvoc::InlineDataHelper::Splitter).map(&:squish)
20
+
21
+ # Iterate over all labels to be added and create them
22
+ Iqvoc::XLLabel.base_class.by_origin(new_origins).each do |l|
23
+ concept.send(labeling_relation_name).create!(:target => l)
24
+ end
25
+ end
26
+ end
27
+
28
+ end
29
+
30
+ def valid_label_language
31
+ (@labelings_by_id || {}).each { |labeling_class_name, origin_mappings|
32
+ origin_mappings.each { |language, new_origins|
33
+ new_origins = new_origins.split(Iqvoc::InlineDataHelper::Splitter)
34
+ Iqvoc::XLLabel.base_class.by_origin(new_origins).each do |label|
35
+ if label.language != language.to_s
36
+ errors.add(:base,
37
+ I18n.t("txt.controllers.versioned_concept.label_error") % label)
38
+ end
39
+ end
40
+ }
41
+ }
42
+ end
43
+
44
+ end
45
+
46
+ module InstanceMethods
47
+
48
+ def labelings_by_id=(hash)
49
+ @labelings_by_id = hash
50
+ end
51
+
52
+ def labelings_by_id(relation_name, language)
53
+ (@labelings_by_id && @labelings_by_id[relation_name] && @labelings_by_id[relation_name][language]) ||
54
+ self.send(relation_name).by_label_language(language).
55
+ map { |l| l.target.origin }.join(Iqvoc::InlineDataHelper::Joiner)
56
+ end
57
+
58
+ end
59
+
60
+ end
61
+ end
62
+ end
@@ -0,0 +1,54 @@
1
+ class Label::Relation::Base < ActiveRecord::Base
2
+
3
+ class_attribute :rdf_namespace, :rdf_predicate
4
+ self.rdf_namespace = nil
5
+ self.rdf_predicate = nil
6
+
7
+ set_table_name 'label_relations'
8
+
9
+ belongs_to :domain, :class_name => "Label::Base"
10
+ belongs_to :range, :class_name => "Label::Base"
11
+
12
+ scope :by_domain, lambda { |domain|
13
+ where(:domain_id => domain)
14
+ }
15
+
16
+ scope :by_range, lambda { |range|
17
+ where(:range_id => range)
18
+ }
19
+
20
+ scope :by_range_origin, lambda { |origin|
21
+ includes(:range).merge(Label::Base.by_origin(origin))
22
+ }
23
+
24
+ scope :range_editor_selectable, lambda {
25
+ # includes(:range) & Iqvoc::XLLabel.base_class.editor_selectable # Doesn't work correctly (kills label_relations.type condition :-( )
26
+ includes(:range).where("labels.published_at IS NOT NULL OR (labels.published_at IS NULL AND labels.published_version_id IS NULL) ")
27
+ }
28
+
29
+ scope :range_in_edit_mode, lambda {
30
+ joins(:range).merge(Iqvoc::XLLabel.base_class.in_edit_mode)
31
+ }
32
+
33
+
34
+ def self.view_section(obj)
35
+ "relations"
36
+ end
37
+
38
+ def self.view_section_sort_key(obj)
39
+ 100
40
+ end
41
+
42
+ def self.partial_name(obj)
43
+ "partials/label/relation/base"
44
+ end
45
+
46
+ def self.edit_partial_name(obj)
47
+ "partials/label/relation/edit_base"
48
+ end
49
+
50
+ def self.only_one_allowed?
51
+ false
52
+ end
53
+
54
+ end
@@ -0,0 +1,12 @@
1
+ class Label::Relation::SKOSXL::Base < Label::Relation::Base
2
+
3
+ self.rdf_namespace = 'skosxl'
4
+
5
+ def build_rdf(document, subject)
6
+ pred = self.class == Label::Relation::SKOSXL::Base ? :labelRelation : self.rdf_predicate
7
+ raise "Match::SKOS::Base#build_rdf: Class #{self.class.name} needs to define self.rdf_namespace and self.rdf_predicate." unless pred
8
+
9
+ subject.send(self.rdf_namespace.camelcase).send(pred, IqRdf.build_uri(range.origin))
10
+ end
11
+
12
+ end
@@ -0,0 +1,219 @@
1
+ # encoding: UTF-8
2
+
3
+ class Label::SKOSXL::Base < Label::Base
4
+
5
+ include Iqvoc::Versioning
6
+
7
+ class_attribute :rdf_namespace, :rdf_class
8
+ self.rdf_namespace = "skosxl"
9
+ self.rdf_class = "Label"
10
+
11
+ # ********** Validations
12
+
13
+ validate :two_versions_exist, :on => :create
14
+ validate :origin_has_to_be_escaped
15
+
16
+ # ********** Hooks
17
+
18
+ after_initialize do
19
+ @full_validation = false
20
+ end
21
+
22
+ after_save do |label|
23
+ # Handle save or destruction of inline relations for use with widgets
24
+ (@inline_assigned_relations ||= {}).each do |relation_class_name, origins|
25
+ # Remove all associated labelings of the given type
26
+ label.send(relation_class_name.to_relation_name).destroy_all
27
+
28
+ # Recreate relations reflecting the widget's parameters
29
+ Iqvoc::XLLabel.base_class.by_origin(origins).each do |l|
30
+ label.send(relation_class_name.to_relation_name).create(:range => l)
31
+ end
32
+ end
33
+ end
34
+
35
+ # ********** "Static"/unconfigureable relations
36
+
37
+ @nested_relations = [] # Will be marked as nested attributes later
38
+
39
+ has_many :labelings, :class_name => 'Labeling::Base', :foreign_key => 'target_id', :dependent => :destroy
40
+ has_many :concepts, :through => :labelings, :source => :owner
41
+ include_to_deep_cloning(:labelings)
42
+
43
+ has_many :relations, :foreign_key => 'domain_id', :class_name => 'Label::Relation::Base', :dependent => :destroy
44
+ # Which references are pointing to this label?
45
+ has_many :referenced_by_relations, :foreign_key => 'range_id', :class_name => 'Label::Relation::Base', :dependent => :destroy
46
+ include_to_deep_cloning(:relations, :referenced_by_relations)
47
+
48
+ has_many :notes, :as => :owner, :class_name => 'Note::Base', :dependent => :destroy
49
+ has_many :annotations, :through => :notes, :source => :annotations
50
+ include_to_deep_cloning(:notes => :annotations)
51
+
52
+ # ************** "Dynamic"/configureable relations
53
+
54
+ Iqvoc::XLLabel.note_class_names.each do |note_class_name|
55
+ has_many note_class_name.to_relation_name, :as => :owner, :class_name => note_class_name, :dependent => :destroy
56
+ @nested_relations << note_class_name.to_relation_name
57
+ end
58
+
59
+ Iqvoc::XLLabel.relation_class_names.each do |relation_class_name|
60
+ has_many relation_class_name.to_relation_name,
61
+ :foreign_key => 'domain_id',
62
+ :class_name => relation_class_name,
63
+ :dependent => :destroy
64
+
65
+ # Serialized setters and getters (\r\n or , separated)
66
+ define_method("inline_#{relation_class_name.to_relation_name}".to_sym) do
67
+ (@inline_assigned_relations && @inline_assigned_relations[relation_class_name]) ||
68
+ self.send(relation_class_name.to_relation_name).map { |r| r.range.origin }.uniq
69
+ end
70
+
71
+ define_method("inline_#{relation_class_name.to_relation_name}=".to_sym) do |value|
72
+ # write to instance variable and write it on after_save
73
+ (@inline_assigned_relations ||= {})[relation_class_name] = value.
74
+ split(/\r\n|, */).map(&:strip).reject(&:blank?).uniq # XXX: use Iqvoc::InlineDataHelper?
75
+ end
76
+ end
77
+
78
+ Iqvoc::XLLabel.additional_association_classes.each do |association_class, foreign_key|
79
+ has_many association_class.name.to_relation_name, :class_name => association_class.name, :foreign_key => foreign_key, :dependent => :destroy
80
+ include_to_deep_cloning(association_class.deep_cloning_relations)
81
+ association_class.referenced_by(self)
82
+ end
83
+
84
+ # ********** Relation Stuff
85
+
86
+ @nested_relations.each do |relation|
87
+ accepts_nested_attributes_for relation, :allow_destroy => true, :reject_if => Proc.new {|attrs| attrs[:value].blank? }
88
+ end
89
+
90
+ # ********** Scopes
91
+
92
+ scope :by_origin, lambda { |origin|
93
+ where(:origin => origin)
94
+ }
95
+
96
+ scope :with_associations, lambda { includes(:labelings => :owner) }
97
+
98
+ scope :for_dashboard, lambda {
99
+ unpublished_or_follow_up.
100
+ includes(:locking_user)
101
+ }
102
+
103
+ # ********** Methods
104
+
105
+ # def self.single_query(params = {})
106
+ # query_str = build_query_string(params)
107
+ #
108
+ # by_query_value(query_str).
109
+ # by_language(params[:languages].to_a).
110
+ # published.
111
+ # order("LOWER(#{Label::Base.table_name}.value)")
112
+ # end
113
+
114
+ # def self.search_result_partial_name
115
+ # 'partials/labeling/skosxl/search_result'
116
+ # end
117
+
118
+ def self.new_link_partial_name
119
+ "partials/label/skosxl/new_link_base"
120
+ end
121
+
122
+ def self.edit_link_partial_name
123
+ "partials/label/skosxl/edit_link_base"
124
+ end
125
+
126
+ def self.from_rdf(str)
127
+ h = Iqvoc::RdfHelper.split_literal(str)
128
+ self.new(:value => h[:value], :language => h[:language])
129
+ end
130
+
131
+ def self.from_rdf!(str)
132
+ self.from_rdf(str).save!
133
+ end
134
+
135
+ def build_rdf_subject(document, controller, &block)
136
+ ns = IqRdf::Namespace.find_namespace_class(self.rdf_namespace.to_sym)
137
+ raise "Namespace '#{rdf_namespace}' is not defined in IqRdf document." unless ns
138
+ IqRdf.build_uri(self.origin, ns.build_uri(self.rdf_class), &block)
139
+ end
140
+
141
+ def concepts_for_labeling_class(labeling_class)
142
+ labeling_class = labeling_class.name if labeling_class < ActiveRecord::Base # Use the class name string
143
+ labelings.select{ |l| l.class.name == labeling_class.to_s }.map(&:owner)
144
+ end
145
+
146
+ def related_labels_for_relation_class(relation_class)
147
+ relation_class = relation_class.name if relation_class < ActiveRecord::Base # Use the class name string
148
+ relations.select{ |rel| rel.class.name == relation_class }.map(&:range)
149
+ end
150
+
151
+ def notes_for_class(note_class)
152
+ note_class = note_class.name if note_class < ActiveRecord::Base # Use the class name string
153
+ notes.select{ |note| note.class.name == note_class }
154
+ end
155
+
156
+ def from_rdf(str)
157
+ h = Iqvoc::RdfHelper.split_literal(str)
158
+ self.value = h[:value]
159
+ self.language = h[:language]
160
+ self
161
+ end
162
+
163
+ def from_rdf!(str)
164
+ from_rdf(str)
165
+ save(:validate => false)
166
+ end
167
+
168
+ def to_param
169
+ origin
170
+ end
171
+
172
+ def has_concept_or_label_relations?
173
+ # Check if one of the additional association methods return elements
174
+ Iqvoc::XLLabel.additional_association_classes.each do |association_class, foreign_key|
175
+ return true if send(association_class.name.to_relation_name).count > 0
176
+ end
177
+ end
178
+
179
+ def save_with_full_validation!
180
+ @full_validation = true
181
+ save!
182
+ end
183
+
184
+ # FIXME: should not @full_validation be set back to the value it had before??? This method changes the state!
185
+ def valid_with_full_validation?
186
+ @full_validation = true
187
+ valid?
188
+ end
189
+
190
+ def invalid_with_full_validation?
191
+ @full_validation = true
192
+ invalid?
193
+ end
194
+
195
+ # Responsible for displaying a warning message about
196
+ # associated objects which are currently edited y another user.
197
+ def associated_objects_in_editing_mode
198
+ {
199
+ :label_relations => Label::Relation::Base.by_domain(id).range_in_edit_mode
200
+ }
201
+ end
202
+
203
+ protected
204
+
205
+ # Validations
206
+
207
+ def origin_has_to_be_escaped
208
+ if origin != OriginMapping.merge(origin)
209
+ errors.add :origin, I18n.t("txt.models.label.origin_invalid")
210
+ end
211
+ end
212
+
213
+ def two_versions_exist
214
+ if Label::SKOSXL::Base.by_origin(origin).count >= 2
215
+ errors.add :base, I18n.t("txt.models.label.version_error")
216
+ end
217
+ end
218
+
219
+ end