rtm-activerecord 0.2.0

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.
Files changed (38) hide show
  1. data/DISCLAIMER +13 -0
  2. data/LICENSE +201 -0
  3. data/README +4 -0
  4. data/lib/rtm/activerecord/001_initial_schema.rb +119 -0
  5. data/lib/rtm/activerecord/association_and_role.rb +54 -0
  6. data/lib/rtm/activerecord/base.rb +83 -0
  7. data/lib/rtm/activerecord/connect.rb +106 -0
  8. data/lib/rtm/activerecord/io/from_xtm2.rb +266 -0
  9. data/lib/rtm/activerecord/io/from_xtm2_libxml.rb +97 -0
  10. data/lib/rtm/activerecord/io/to_jtm.rb +141 -0
  11. data/lib/rtm/activerecord/io/to_string.rb +130 -0
  12. data/lib/rtm/activerecord/io/to_xtm1.rb +162 -0
  13. data/lib/rtm/activerecord/io/to_xtm2.rb +163 -0
  14. data/lib/rtm/activerecord/io/to_yaml.rb +132 -0
  15. data/lib/rtm/activerecord/literal_index.rb +38 -0
  16. data/lib/rtm/activerecord/locators.rb +58 -0
  17. data/lib/rtm/activerecord/merging.rb +310 -0
  18. data/lib/rtm/activerecord/name_variant_occurrence.rb +86 -0
  19. data/lib/rtm/activerecord/persistent_code_output.rb +22 -0
  20. data/lib/rtm/activerecord/quaaxtm2rtm.rb +116 -0
  21. data/lib/rtm/activerecord/quaaxtm2rtmviews.rb +137 -0
  22. data/lib/rtm/activerecord/set_wrapper.rb +101 -0
  23. data/lib/rtm/activerecord/sugar/association/hash_access.rb +22 -0
  24. data/lib/rtm/activerecord/sugar/role/counterparts.rb +56 -0
  25. data/lib/rtm/activerecord/sugar/topic/characteristics.rb +15 -0
  26. data/lib/rtm/activerecord/sugar/topic/counterparts.rb +18 -0
  27. data/lib/rtm/activerecord/sugar/topic/hash_access.rb +78 -0
  28. data/lib/rtm/activerecord/sugar/topic/identifier_direct.rb +14 -0
  29. data/lib/rtm/activerecord/sugar/topic/predefined_associations.rb +53 -0
  30. data/lib/rtm/activerecord/tm_construct.rb +66 -0
  31. data/lib/rtm/activerecord/tm_delegator.rb +417 -0
  32. data/lib/rtm/activerecord/tm_set_delegator.rb +226 -0
  33. data/lib/rtm/activerecord/tmdm.rb +309 -0
  34. data/lib/rtm/activerecord/topic.rb +204 -0
  35. data/lib/rtm/activerecord/topic_map.rb +435 -0
  36. data/lib/rtm/activerecord/traverse_associations.rb +90 -0
  37. data/lib/rtm/activerecord.rb +106 -0
  38. metadata +120 -0
@@ -0,0 +1,132 @@
1
+ # Copyright: Copyright 2009 Topic Maps Lab, University of Leipzig.
2
+ # License: Apache License, Version 2.0
3
+
4
+ module RTM::AR::IO
5
+ # YAML Export.
6
+ # Each Topic Maps Construct gets a to_xtm2 method.
7
+ module TOYAML
8
+
9
+ module TopicMap
10
+ def to_yaml_hash(*a)
11
+ y={}
12
+ #j['base_locator'] = base_locator, # with absolute item_identifiers its not needed
13
+ y['reifier'] = reifier.to_yaml_ref if reifier
14
+ y['item_identifiers'] = item_identifiers.map{|i| i.reference} unless item_identifiers.empty?
15
+ y['topics'] = topics.map{|i| i.to_yaml_hash} unless topics.empty?
16
+ y['associations'] = associations.map{|i| i.to_yaml_hash} unless associations.empty?
17
+ y
18
+ end
19
+ # returns the YAML representation of this topic map
20
+ def to_yaml(*a)
21
+ to_yaml_hash.to_yaml(*a)
22
+ end
23
+ end
24
+
25
+ module Topic
26
+ # returns the YAML representation of this topic
27
+ def to_yaml_hash(*a)
28
+ y={}
29
+ y['item_identifiers'] = item_identifiers.map{|i| i.reference} unless item_identifiers.empty?
30
+ y['subject_identifiers'] = subject_identifiers.map{|i| i.reference} unless subject_identifiers.empty?
31
+ unless y['item_identifiers'] || y['subject_identifiers']
32
+ y['item_identifiers'] = [to_yaml_ref]
33
+ end
34
+ y['subject_locators'] = subject_locators.map{|i| i.reference} unless subject_locators.empty?
35
+ y['names'] = names.map{|i| i.to_yaml_hash} unless names.empty?
36
+ y['occurrences'] = occurrences.map{|i| i.to_yaml_hash} unless occurrences.empty?
37
+ y
38
+ end
39
+ def to_yaml(*a)
40
+ to_yaml_hash.to_yaml(*a)
41
+ end
42
+ def to_yaml_ref
43
+ if subject_identifiers.first
44
+ return subject_identifiers.first.reference
45
+ end
46
+ if item_identifiers.first
47
+ return item_identifiers.first.reference
48
+ end
49
+ "t#{id}"
50
+ end
51
+ end
52
+
53
+ module Association
54
+ def to_yaml_hash(*a)
55
+ y={}
56
+ y['reifier'] = reifier.to_yaml_ref if reifier
57
+ y['item_identifiers'] = item_identifiers.map{|i| i.reference} unless item_identifiers.empty?
58
+ y['type'] = type.to_yaml_ref if type
59
+ y['scope'] = scope.map{|i| i.to_yaml_hash} unless scope.empty?
60
+ y['roles'] = roles.map{|i| i.to_yaml_hash} unless roles.empty?
61
+ y
62
+ end
63
+ # returns the YAML representation of this association
64
+ def to_yaml(*a)
65
+ to_yaml_hash.to_yaml(*a)
66
+ end
67
+ end
68
+
69
+ module TopicName
70
+ def to_yaml_hash(*a)
71
+ y={}
72
+ y['reifier'] = reifier.to_yaml_ref if reifier
73
+ y['item_identifiers'] = item_identifiers.map{|i| i.reference} unless item_identifiers.empty?
74
+ y['value'] = value if value
75
+ y['type'] = type.to_yaml_ref if type
76
+ y['scope'] = scope.map{|i| i.to_yaml_hash} unless scope.empty?
77
+ y['variants'] = variants.map{|i| i.to_yaml_hash} unless variants.empty?
78
+ y
79
+ end
80
+ def to_yaml(*a)
81
+ to_yaml_hash.to_yaml(*a)
82
+ end
83
+ end
84
+
85
+ module Occurrence
86
+ def to_yaml_hash(*a)
87
+ y={}
88
+ y['reifier'] = reifier.to_yaml_ref if reifier
89
+ y['item_identifiers'] = item_identifiers.map{|i| i.reference} unless item_identifiers.empty?
90
+ y['value'] = value if value
91
+ y['datatype'] = datatype if datatype
92
+ y['type'] = type.to_yaml_ref if type
93
+ y['scope'] = scope.map{|i| i.to_yaml_hash} unless scope.empty?
94
+ y
95
+ end
96
+ def to_yaml(*a)
97
+ to_yaml_hash.to_yaml(*a)
98
+ end
99
+ end
100
+
101
+ module AssociationRole
102
+ def to_yaml_hash(*a)
103
+ y={}
104
+ y['reifier'] = reifier.to_yaml_ref if reifier
105
+ y['item_identifiers'] = item_identifiers.map{|i| i.reference} unless item_identifiers.empty?
106
+ y['player'] = player.to_yaml_ref if player
107
+ y['type'] = type.to_yaml_ref if type
108
+ y
109
+ end
110
+ def to_yaml(*a)
111
+ to_yaml_hash.to_yaml(*a)
112
+ end
113
+ end
114
+
115
+ module Variant
116
+ def to_yaml_hash(*a)
117
+ y={}
118
+ y['reifier'] = reifier.to_yaml_ref if reifier
119
+ y['item_identifiers'] = item_identifiers.map{|i| i.reference} unless item_identifiers.empty?
120
+ y['value'] = value if value
121
+ y['scope'] = scope.map{|i| i.to_yaml_hash} unless scope.empty?
122
+ y
123
+ end
124
+ def to_yaml(*a)
125
+ to_yaml_hash.to_yaml(*a)
126
+ end
127
+ end
128
+
129
+ RTM::AR.register_extension self
130
+ end
131
+ end
132
+
@@ -0,0 +1,38 @@
1
+ module RTM::AR
2
+ class Index
3
+ attr_accessor :topic_map
4
+ attr_accessor :itopic_map # the internal AR object
5
+ def initialize(tm)
6
+ @topic_map = tm
7
+ @itopic_map = tm.__getobj__
8
+ end
9
+ def close
10
+ end
11
+ def isAutoUpdated
12
+ true
13
+ end
14
+ def isOpen
15
+ true
16
+ end
17
+ def open
18
+ end
19
+ def reindex
20
+ end
21
+ end
22
+ class LiteralIndex < Index
23
+ def names(value)
24
+ Names.wrap(self.itopic_map.names.find(:all,:conditions => ["value = ?", value]))
25
+ end
26
+ alias :getNames :names
27
+
28
+ def occurrences(value)
29
+ Occurrences.wrap(self.itopic_map.occurrences.find(:all,:conditions => ["value = ?", value]))
30
+ end
31
+ alias :getOccurrences :occurrences
32
+
33
+ def variants(value)
34
+ Variants.wrap(TMDM::Variant.find(:all,:conditions => ["value = ?", value]).select{|v| v.topic_map == self.itopic_map})
35
+ end
36
+ alias :getVariants :variants
37
+ end
38
+ end
@@ -0,0 +1,58 @@
1
+ # Copyright: Copyright 2009 Topic Maps Lab, University of Leipzig.
2
+ # License: Apache License, Version 2.0
3
+
4
+ module RTM::AR
5
+ class Locator < TMDelegator
6
+ include RTM::Locator
7
+
8
+ delegate :+
9
+ delegate :-
10
+ #delegate :==
11
+ delegate :id
12
+
13
+ delegate :get
14
+ delegate :hash
15
+ delegate :resolve_relative
16
+ delegate :to_s, :to => :reference
17
+ delegate :to_uri
18
+ delegate :uri
19
+ delegate :reference, :rw => true, :save => true
20
+ alias :value :reference
21
+ alias :value= :reference=
22
+ alias :v :reference
23
+ alias :v= :reference=
24
+
25
+ equality [:reference]
26
+
27
+ def self.wrap(obj)
28
+ return nil unless obj
29
+ raise "Double wrapping" if obj.respond_to?(:__getobj__)
30
+ case obj.class.name
31
+ when "RTM::AR::TMDM::ItemIdentifier"
32
+ ItemIdentifier.wrap(obj)
33
+ when "RTM::AR::TMDM::SubjectIdentifier"
34
+ SubjectIdentifier.wrap(obj)
35
+ when "RTM::AR::TMDM::SubjectLocator"
36
+ SubjectLocator.wrap(obj)
37
+ else
38
+ raise "Can't wrap object. Class for wrapping #{obj.class} unknown (object: #{obj})"
39
+ end
40
+ end
41
+ end
42
+
43
+ class ItemIdentifier < Locator
44
+ include RTM::ItemIdentifier
45
+ wrapper_cache
46
+ property :construct, :type => :Construct, :wrap => true
47
+ end
48
+ class SubjectIdentifier < Locator
49
+ include RTM::SubjectIdentifier
50
+ wrapper_cache
51
+ property :topic, :type => :Topic, :wrap => true
52
+ end
53
+ class SubjectLocator < Locator
54
+ include RTM::SubjectLocator
55
+ wrapper_cache
56
+ property :topic, :type => :Topic, :wrap => true
57
+ end
58
+ end
@@ -0,0 +1,310 @@
1
+ # Copyright: Copyright 2009 Topic Maps Lab, University of Leipzig.
2
+ # License: Apache License, Version 2.0
3
+
4
+ module RTM
5
+ class MergeException < Exception; end
6
+ class TopicMergeException < MergeException; end
7
+ module Merging
8
+ module ReWrap
9
+ protected
10
+ def merge_rewrap(other)
11
+ # let the wrapper point to the new object
12
+ old_getobj = other.__getobj__
13
+ other.__setobj__(self.__getobj__) if self.respond_to?(:__getobj__) && other.respond_to?(:__setobj__)
14
+ # and destroy the old one
15
+ old_getobj.reload
16
+ __getobj__.reload
17
+ old_getobj.destroy
18
+ end
19
+ end
20
+ module MergeItemIdentifiers
21
+ protected
22
+ def merge_item_identifiers(other)
23
+ #self.item_identifiers.add_all other.item_identifiers
24
+ RTM::AR::TMDM::ItemIdentifier.move_all(
25
+ ["topic_map_construct_id", other.__getobj__.id, self.__getobj__.id],
26
+ ["topic_map_construct_type", other.__getobj__.class.name, self.__getobj__.class.name]
27
+ )
28
+ end
29
+ end
30
+ module MergeReifiable
31
+ include MergeItemIdentifiers
32
+ include ReWrap
33
+ protected
34
+ def merge_reifiable(other)
35
+ if other.reifier && self.reifier
36
+ self.reifier.merge(other.reifier)
37
+ elsif other.reifier
38
+ self.reifier = other.reifier
39
+ end
40
+ end
41
+ end
42
+
43
+ module Association
44
+ include Merging::MergeReifiable
45
+
46
+ def merge(other)
47
+ # The procedure for merging two association items A and B is given below.
48
+
49
+ # 1. Create a new association item, C.
50
+ # -> we will instead just modify a
51
+
52
+ # 2. Set C's [type] property to the value of A's [type] property. B's value is equal to that of A and need not be taken into account.
53
+ # 3. Set C's [scope] property to the value of A's [scope] property. B's value is equal to that of A and need not be taken into account.
54
+ # 4. Set C's [roles] property to the value of A's [roles] property. B's value is equal to that of A and need not be taken into account.
55
+ # -> nothing to do till here
56
+
57
+ # 5. Set C's [reifier] property to the value of A's [reifier] property if it is not null, and to the value of B's [reifier] property if A's property is null. If both A and B have non-null values, the topic items shall be merged, and the topic item resulting from the merge set as the value of C's [reifier] property.
58
+ self.merge_reifiable other
59
+
60
+ # 6. Set C's [item identifiers] property to the union of the values of A's and B's [item identifiers] properties.
61
+ self.merge_item_identifiers other
62
+
63
+ # 7. Remove A and B from the [associations] property of the topic map item in their [parent] properties, and add C.
64
+ #self.parent.associations.remove other
65
+
66
+ # let the wrapper point to the new object
67
+ #other.__setobj__(self.__getobj__) if self.respond_to?(:__getobj__) && other.respond_to?(:__setobj__)
68
+ self.merge_rewrap other
69
+
70
+ self
71
+ end
72
+ end
73
+
74
+ module Role
75
+ include Merging::MergeReifiable
76
+
77
+ def merge(other)
78
+ # The procedure for merging two association role items A and B is given below.
79
+ # -> we will instead just modify a
80
+
81
+ # 1. Create a new association role item, C.
82
+ # 2. Set C's [player] property to the value of A's [player] property. B's value is equal to that of A and need not be taken into account.
83
+ # 3. Set C's [type] property to the value of A's [type] property. B's value is equal to that of A and need not be taken into account.
84
+ # -> nothing to do till here
85
+
86
+ # 4. Set C's [item identifiers] property to the union of the values of A's and B's [item identifiers] properties.
87
+ self.merge_item_identifiers other
88
+
89
+ # 5. Set C's [reifier] property to the value of A's [reifier] property if it is not null,
90
+ # and to the value of B's [reifier] property if A's property is null.
91
+ # If both A and B have non-null values, the topic items shall be merged,
92
+ # and the topic item resulting from the merge set as the value of C's [reifier] property.
93
+ self.merge_reifiable other
94
+
95
+ # 6. Remove A and B from the [roles] property of the association item in their [parent] properties, and add C.
96
+ #self.parent.roles.remove other
97
+
98
+ #puts "#{self.parent.object_id} and #{other.parent.object_id}"
99
+
100
+ # let the wrapper point to the new object
101
+ #other.__setobj__(self.__getobj__) if self.respond_to?(:__getobj__) && other.respond_to?(:__setobj__)
102
+ self.merge_rewrap other
103
+
104
+ self
105
+ end
106
+ end
107
+
108
+ module Occurrence
109
+ include Merging::MergeReifiable
110
+
111
+ def merge(other)
112
+ # 1. Create a new occurrence item, C.
113
+ # -> we will instead just modify a
114
+
115
+ # 2. Set C's [value] property to the value of A's [value] property. B's value is equal to that of A and need not be taken into account.
116
+ # 3. Set C's [datatype] property to the value of A's [datatype] property. B's value is equal to that of A and need not be taken into account.
117
+ # 4. Set C's [scope] property to the value of A's [scope] property. B's value is equal to that of A and need not be taken into account.
118
+ # 5. Set C's [type] property to the value of A's [type] property. B's value is equal to that of A and need not be taken into account.
119
+ # -> nothing to do till here
120
+
121
+ # 6. Set C's [reifier] property to the value of A's [reifier] property if it is not null, and to the value of B's [reifier] property if A's property is null. If both A and B have non-null values, the topic items shall be merged, and the topic item resulting from the merge set as the value of C's [reifier] property.
122
+ self.merge_reifiable other
123
+
124
+ # 7. Set C's [item identifiers] property to the union of the values of A's and B's [item identifiers] properties.
125
+ self.merge_item_identifiers other
126
+
127
+ # 8. Remove A and B from the [occurrences] property of the topic item in their [parent] properties, and add C.
128
+ #self.parent.occurrences.remove other
129
+
130
+ # let the wrapper point to the new object
131
+ #other.__setobj__(self.__getobj__) if self.respond_to?(:__getobj__) && other.respond_to?(:__setobj__)
132
+ self.merge_rewrap other
133
+
134
+ self
135
+ end
136
+ end
137
+
138
+ module Topic
139
+ include Merging::ReWrap
140
+ include Merging::MergeItemIdentifiers
141
+
142
+ def merge(other)
143
+ return unless other
144
+ # The procedure for merging two topic items A and B
145
+ # -> we will instead just modify a
146
+ # (whose [parent] properties shall contain the same topic map item) is given below.
147
+ raise TopicMergeException, "Both topics must belong to the same topic map!" if self.parent.__getobj__ != other.parent.__getobj__
148
+ # It is an error if A and B both have non-null values in their [reified] properties which are different.
149
+ raise TopicMergeException, "The Topics must not reify different things." if self.reified && other.reified && self.reified.__getobj__ != other.reified.__getobj__
150
+
151
+ # 1. Create a new topic item C.
152
+ # 2. Replace A by C wherever it appears in one of the following properties
153
+ # of an information item: [topics], [scope], [type], [player], and [reifier].
154
+ # -> nothing to do here
155
+
156
+ # 3. Repeat for B.
157
+ # [topics]
158
+ # done below, in rewrap
159
+ # [scope]
160
+ RTM::AR::TMDM::ScopedObjectsTopic.move_all(["topic_id", other.__getobj__.id, self.__getobj__.id])
161
+ # [type]
162
+ RTM::AR::TMDM::Association.move_all(["ttype_id", other.__getobj__.id, self.__getobj__.id])
163
+ RTM::AR::TMDM::Role.move_all(["ttype_id", other.__getobj__.id, self.__getobj__.id])
164
+ RTM::AR::TMDM::Name.move_all(["ttype_id", other.__getobj__.id, self.__getobj__.id])
165
+ RTM::AR::TMDM::Occurrence.move_all(["ttype_id", other.__getobj__.id, self.__getobj__.id])
166
+
167
+ # [player]
168
+ RTM::AR::TMDM::AssociationRole.move_all(["topic_id", other.__getobj__.id, self.__getobj__.id])
169
+
170
+ # [reifier]
171
+ if other.reified
172
+ self.reified = other.reified
173
+ end
174
+ # 4. Set C's [topic names] property to the union of the values of A and B's [topic names] properties.
175
+ #self.names.add_all other.names
176
+ count = RTM::AR::TMDM::Name.move_all(["topic_id", other.__getobj__.id, self.__getobj__.id])
177
+ if count != 0 && count != names.size
178
+ names.each_with_index do |n,i|
179
+ (i+1).upto(names.size-1) do |j|
180
+ if n == names[j]
181
+ n.merge names[j]
182
+ end
183
+ end
184
+ end
185
+ end
186
+
187
+ # 5. Set C's [occurrences] property to the union of the values of A and B's [occurrences] properties.
188
+ #self.occurrences.add_all other.occurrences
189
+ RTM::AR::TMDM::Occurrence.move_all(["topic_id", other.__getobj__.id, self.__getobj__.id])
190
+ if count != 0 && count != occurrences.size
191
+ occurrences.each_with_index do |o,i|
192
+ (i+1).upto(occurrences.size-1) do |j|
193
+ if o == occurrences[j]
194
+ o.merge occurrences[j]
195
+ end
196
+ end
197
+ end
198
+ end
199
+
200
+ # 6. Set C's [subject identifiers] property to the union of the values of A and B's [subject identifiers] properties.
201
+ #self.subject_identifiers.add_all other.subject_identifiers
202
+ RTM::AR::TMDM::SubjectIdentifier.move_all(["topic_id", other.__getobj__.id, self.__getobj__.id])
203
+
204
+ # 7. Set C's [subject locators] property to the union of the values of A and B's [subject locators] properties.
205
+ #self.subject_locators.add_all other.subject_locators
206
+ RTM::AR::TMDM::SubjectLocator.move_all(["topic_id", other.__getobj__.id, self.__getobj__.id])
207
+
208
+ # 8. Set C's [item identifiers] property to the union of the values of A and B's [item identifiers] properties.
209
+ #self.item_identifiers.add_all other.item_identifiers
210
+ #RTM::AR::TMDM::ItemIdentifier.update_all "topic_map_construct_id = #{self.__getobj__.id}, topic_map_construct_type = '#{self.__getobj__.class.name}'", "topic_map_construct_id = #{other.__getobj__.id} and topic_map_construct_type = '#{other.__getobj__.class.name}'"
211
+ RTM::AR::TMDM::ItemIdentifier.move_all(
212
+ ["topic_map_construct_id", other.__getobj__.id, self.__getobj__.id],
213
+ ["topic_map_construct_type", other.__getobj__.class.name, self.__getobj__.class.name]
214
+ )
215
+
216
+ self.merge_rewrap other
217
+
218
+ self
219
+ end
220
+ alias :merge_in :merge
221
+ end
222
+
223
+ module TopicMap
224
+ include Merging::MergeReifiable
225
+
226
+ def merge(other) # other:TopicMap
227
+ self.topics.add_all other.topics
228
+ self.associations.add_all other.associations
229
+ self.merge_reifiable other
230
+ self.merge_item_identifiers other
231
+
232
+ self.merge_rewrap other
233
+ self
234
+ end
235
+ alias :merge_in :merge
236
+ end
237
+
238
+ module Name
239
+ def merge(other)
240
+ # The procedure for merging two topic name items A and B is given below.
241
+ # -> we will instead just modify a
242
+
243
+ # 1. Create a new topic name item C.
244
+ # 2. Set C's [value] property to the value of the [value] property of A. B's value is equal that of A and need not be taken into account.
245
+ # 3. Set C's [type] property to the value of the [type] property of A. B's value is equal that of A and need not be taken into account.
246
+ # 4. Set C's [scope] property to the value of the [scope] property of A. B's value is equal that of A and need not be taken into account.
247
+ # -> nothing to do till here
248
+
249
+ # 5. Set C's [variants] property to the union of the [variants] properties of A and B.
250
+ #self.variants.add_all other.variants
251
+ count = RTM::AR::TMDM::Variant.move_all(["name_id", other.__getobj__.id, self.__getobj__.id])
252
+ if count != 0 && count != variants.size
253
+ variants.each_with_index do |v,i|
254
+ (i+1).upto(variants.size-1) do |j|
255
+ if v == variants[j]
256
+ v.merge variants[j]
257
+ end
258
+ end
259
+ end
260
+ end
261
+
262
+ # 6. Set C's [reifier] property to the value of A's [reifier] property if it is not null, and to the value of B's [reifier] property if A's property is null. If both A and B have non-null values, the topic items shall be merged, and the topic item resulting from the merge be set as the value of C's [reifier] property.
263
+ self.merge_reifiable other
264
+
265
+ # 7. Set C's [item identifiers] property to the union of the value of the [item identifiers] properties of A and B.
266
+ self.merge_item_identifiers other
267
+
268
+ # 8. Remove A and B from the [topic names] property of the topic item in their [parent] properties, and add C.
269
+ #self.parent.names.remove other
270
+
271
+ # let the wrapper point to the new object
272
+ #other.__setobj__(self.__getobj__) if self.respond_to?(:__getobj__) && other.respond_to?(:__setobj__)
273
+ self.merge_rewrap other
274
+
275
+ self
276
+ end
277
+ end
278
+
279
+ module Variant
280
+ include Merging::MergeReifiable
281
+
282
+ def merge(other)
283
+ #The procedure for merging two variant items A and B is given below.
284
+ # -> we will instead just modify a
285
+
286
+ # 1. Create a new variant item, C.
287
+ # 2. Set C's [value] property to the value of A's [value] property. B's value is equal to that of A and need not be taken into account.
288
+ # 3. Set C's [datatype] property to the value of A's [datatype] property. B's value is equal to that of A and need not be taken into account.
289
+ # 4. Set C's [scope] property to the value of A's [scope] property. B's value is equal to that of A and need not be taken into account.
290
+ # -> nothing to do till here
291
+
292
+ # 5. Set C's [reifier] property to the value of A's [reifier] property if it is not null, and to the value of B's [reifier] property if A's property is null. If both A and B have non-null values, the topic items shall be merged, and the topic item resulting from the merge set as the value of C's [reifier] property.
293
+ self.merge_reifiable other
294
+
295
+ # 6. Set C's [item identifiers] property to the union of the values of A's and B's [item identifiers] properties.
296
+ self.merge_item_identifiers other
297
+
298
+ # 7. Remove A and B from the [variants] property of the topic name item in their [parent] properties, and add C.
299
+ #self.parent.variants.remove other
300
+
301
+ # let the wrapper point to the new object
302
+ #other.__setobj__(self.__getobj__) if self.respond_to?(:__getobj__) && other.respond_to?(:__setobj__)
303
+ self.merge_rewrap other
304
+
305
+ self
306
+ end
307
+ end
308
+ RTM.register_extension( self )
309
+ end
310
+ end