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,141 @@
1
+ # Copyright: Copyright 2009 Topic Maps Lab, University of Leipzig.
2
+ # License: Apache License, Version 2.0
3
+
4
+ module RTM::AR::IO
5
+ # JTM Export.
6
+ # Each Topic Maps Construct gets a to_jtm method.
7
+ module TOJTM
8
+
9
+ module TopicMap
10
+ # returns the JTM representation of this topic map
11
+ def to_jtm_hash(*a)
12
+ j={}
13
+ #j['base_locator'] = base_locator, # with absolute item_identifiers its not needed
14
+ j['reifier'] = reifier.to_jtm_ref if reifier
15
+ j['item_identifiers'] = item_identifiers.map{|i| i.reference} unless item_identifiers.empty?
16
+ j['topics'] = topics.map{|i| i.to_jtm_hash} unless topics.empty?
17
+ j['associations'] = associations.map{|i| i.to_jtm_hash} unless associations.empty?
18
+ j
19
+ end
20
+ def to_jtm(*a)
21
+ to_jtm_hash.to_json(*a)
22
+ end
23
+ alias :to_json :to_jtm
24
+ end
25
+
26
+ module Topic
27
+ # returns the JTM representation of this topic
28
+ def to_jtm_hash(*a)
29
+ j={}
30
+ j['item_identifiers'] = item_identifiers.map{|i| i.reference} unless item_identifiers.empty?
31
+ j['subject_identifiers'] = subject_identifiers.map{|i| i.reference} unless subject_identifiers.empty?
32
+ unless j['item_identifiers'] || j['subject_identifiers']
33
+ j['item_identifiers'] = [to_jtm_ref]
34
+ end
35
+ j['subject_locators'] = subject_locators.map{|i| i.reference} unless subject_locators.empty?
36
+ j['names'] = names.map{|i| i.to_jtm_hash} unless names.empty?
37
+ j['occurrences'] = occurrences.map{|i| i.to_jtm_hash} unless occurrences.empty?
38
+ j
39
+ end
40
+ def to_jtm(*a)
41
+ to_jtm_hash.to_json(*a)
42
+ end
43
+ alias :to_json :to_jtm
44
+
45
+ def to_jtm_ref
46
+ if subject_identifiers.first
47
+ return subject_identifiers.first.reference
48
+ end
49
+ if item_identifiers.first
50
+ return item_identifiers.first.reference
51
+ end
52
+ "t#{id}"
53
+ end
54
+ end
55
+
56
+ module Association
57
+ # returns the JTM representation of this association
58
+ def to_jtm_hash(*a)
59
+ j={}
60
+ j['reifier'] = reifier.to_jtm_ref if reifier
61
+ j['item_identifiers'] = item_identifiers.map{|i| i.reference} unless item_identifiers.empty?
62
+ j['type'] = type.to_jtm_ref if type
63
+ j['scope'] = scope.map{|i| i.to_jtm_hash} unless scope.empty?
64
+ j['roles'] = roles.map{|i| i.to_jtm_hash} unless roles.empty?
65
+ j
66
+ end
67
+ def to_jtm(*a)
68
+ to_jtm_hash.to_json(*a)
69
+ end
70
+ alias :to_json :to_jtm
71
+
72
+ end
73
+
74
+ module TopicName
75
+ def to_jtm_hash(*a)
76
+ j={}
77
+ j['reifier'] = reifier.to_jtm_ref if reifier
78
+ j['item_identifiers'] = item_identifiers.map{|i| i.reference} unless item_identifiers.empty?
79
+ j['value'] = value if value
80
+ j['type'] = type.to_jtm_ref if type
81
+ j['scope'] = scope.map{|i| i.to_jtm_hash} unless scope.empty?
82
+ j['variants'] = variants.map{|i| i.to_jtm_hash} unless variants.empty?
83
+ j
84
+ end
85
+ def to_jtm(*a)
86
+ to_jtm_hash.to_json(*a)
87
+ end
88
+ alias :to_json :to_jtm
89
+ end
90
+
91
+ module Occurrence
92
+ def to_jtm_hash(*a)
93
+ j={}
94
+ j['reifier'] = reifier.to_jtm_ref if reifier
95
+ j['item_identifiers'] = item_identifiers.map{|i| i.reference} unless item_identifiers.empty?
96
+ j['value'] = value if value
97
+ j['datatype'] = datatype if datatype
98
+ j['type'] = type.to_jtm_ref if type
99
+ j['scope'] = scope.map{|i| i.to_jtm_hash} unless scope.empty?
100
+ j
101
+ end
102
+ def to_jtm(*a)
103
+ to_jtm_hash.to_json(*a)
104
+ end
105
+ alias :to_json :to_jtm
106
+ end
107
+
108
+ module AssociationRole
109
+ def to_jtm_hash(*a)
110
+ j={}
111
+ j['reifier'] = reifier.to_jtm_ref if reifier
112
+ j['item_identifiers'] = item_identifiers.map{|i| i.reference} unless item_identifiers.empty?
113
+ j['player'] = player.to_jtm_ref if player
114
+ j['type'] = type.to_jtm_ref if type
115
+ j
116
+ end
117
+ def to_jtm(*a)
118
+ to_jtm_hash.to_json(*a)
119
+ end
120
+ alias :to_json :to_jtm
121
+ end
122
+
123
+ module Variant
124
+ def to_jtm_hash(*a)
125
+ j={}
126
+ j['reifier'] = reifier.to_jtm_ref if reifier
127
+ j['item_identifiers'] = item_identifiers.map{|i| i.reference} unless item_identifiers.empty?
128
+ j['value'] = value if value
129
+ j['scope'] = scope.map{|i| i.to_jtm_hash} unless scope.empty?
130
+ j
131
+ end
132
+ def to_jtm(*a)
133
+ to_jtm_hash.to_json(*a)
134
+ end
135
+ alias :to_json :to_jtm
136
+ end
137
+
138
+ RTM::AR.register_extension self
139
+ end
140
+ end
141
+
@@ -0,0 +1,130 @@
1
+ # Copyright: Copyright 2009 Topic Maps Lab, University of Leipzig.
2
+ # License: Apache License, Version 2.0
3
+
4
+ module RTM::AR:IO
5
+ # Each Topic Maps Construct gets a custom to_s method which supports optional :short or :long output.
6
+ module TOSTRING
7
+
8
+ module TopicMap
9
+ # Returns different String representations. Try :short (default), :long, :super (original)
10
+ def to_s(style=:short)
11
+ case style
12
+ when :short
13
+ "#<RTM::TopicMap id=#{id} base_locator=\"#{base_locator}\">"
14
+ when :long
15
+ r = " #{reifier.to_s(:short)}" if reifier
16
+ i = " iids=#{item_identifiers.to_s}" unless item_identifiers.empty?
17
+ "#<RTM::TopicMap id=#{id} base_locator=\"#{base_locator}\"#{r}#{i} topics:#{topics.size} associations:#{associations.size}>"
18
+ else
19
+ super() # these () are needed, otherwise the own parameters are passed in
20
+ end
21
+ end
22
+ end
23
+
24
+ module Topic
25
+ # Returns different String representations. Try :short (default), :long or something else for the original method.
26
+ # :name returns one (random) name for the Topic or an empty string if the topic has no name
27
+ def to_s(style=:short)
28
+ case style
29
+ when :short
30
+ ssid = " sids=#{subject_identifiers.to_s}" unless subject_identifiers.empty?
31
+ sslo = " slos=#{subject_locators.to_s}" unless subject_locators.empty?
32
+ siid = " iids=#{item_identifiers.to_s}" unless item_identifiers.empty?
33
+ "#<RTM::Topic id=#{id}#{ssid}#{sslo}#{siid}>"
34
+ when :long
35
+ ssid = " sids=#{subject_identifiers.to_s}" unless subject_identifiers.empty?
36
+ sslo = " slos=#{subject_locators.to_s}" unless subject_locators.empty?
37
+ siid = " iids=#{item_identifiers.to_s}" unless item_identifiers.empty?
38
+ "#<RTM::Topic id=#{id}#{ssid}#{sslo}#{siid} names:#{names.size} occurrences:#{occurrences.size}>"
39
+ when :name
40
+ return names.first.to_s(:short) if names.first
41
+ return ""
42
+ else
43
+ super() # these () are needed, otherwise the own parameters are passed in
44
+ end
45
+ end
46
+ end
47
+
48
+ module Association
49
+ def to_s(style=:short)
50
+ case style
51
+ when :short
52
+ r = " #{reifier.to_s(:short)}" if reifier
53
+ i = " iids=#{item_identifiers.to_s}" unless item_identifiers.empty?
54
+ "#<RTM::Association id=#{id}#{i}#{r}>"
55
+ when :long
56
+ r = " #{reifier.to_s(:short)}" if reifier
57
+ i = " iids=#{item_identifiers.to_s}" unless item_identifiers.empty?
58
+ "#<RTM::Association id=#{id}#{i}#{r} type=#{type.to_s(:short)} roles=[#{roles.entries.map { |ar| ar.to_s }.join(", ")}]>"
59
+ else
60
+ super() # these () are needed, otherwise the own parameters are passed in
61
+ end
62
+ end
63
+ end
64
+
65
+ module AssociationRole
66
+ def to_s(style=:short)
67
+ case style
68
+ when :short
69
+ r = " #{reifier.to_s(:short)}" if reifier
70
+ i = " iids=#{item_identifiers.to_s}" unless item_identifiers.empty?
71
+ "#<RTM::AssociationRole id=#{id}#{i}#{r}>"
72
+ when :long
73
+ r = " #{reifier.to_s(:short)}" if reifier
74
+ i = " iids=#{item_identifiers.to_s}" unless item_identifiers.empty?
75
+ "#<RTM::Association id=#{id}#{i}#{r} type=#{type.to_s(:short)} player=#{player.to_s(:short)}>"
76
+ else
77
+ super() # these () are needed, otherwise the own parameters are passed in
78
+ end
79
+ end
80
+ end
81
+
82
+ module TopicName
83
+ def to_s(style=:short)
84
+ case style
85
+ when :short
86
+ value
87
+ when :long
88
+ r = " #{reifier.to_s(:short)}" if reifier
89
+ i = " iids=#{item_identifiers.to_s}" unless item_identifiers.empty?
90
+ "#<RTM::TopicName id=#{id}#{i}#{r} type=#{type.to_s(:short)} value=#{value} variants:#{variants.size}>"
91
+ else
92
+ super() # these () are needed, otherwise the own parameters are passed in
93
+ end
94
+ end
95
+ end
96
+
97
+ module Occurrence
98
+ def to_s(style=:short)
99
+ case style
100
+ when :short
101
+ value
102
+ when :long
103
+ r = " #{reifier.to_s(:short)}" if reifier
104
+ i = " iids=#{item_identifiers.to_s}" unless item_identifiers.empty?
105
+ "#<RTM::Occurrence id=#{id}#{i}#{r} type=#{type.to_s(:short)} value=#{value} datatype=#{datatype}>"
106
+ else
107
+ super() # these () are needed, otherwise the own parameters are passed in
108
+ end
109
+ end
110
+ end
111
+
112
+ module Variant
113
+ def to_s(style=:short)
114
+ case style
115
+ when :short
116
+ value
117
+ when :long
118
+ r = " #{reifier.to_s(:short)}" if reifier
119
+ i = " iids=#{item_identifiers.to_s}" unless item_identifiers.empty?
120
+ "#<RTM::Variant id=#{id}#{i}#{r} value=#{value} scope=[scope.to_s]>"
121
+ else
122
+ super() # these () are needed, otherwise the own parameters are passed in
123
+ end
124
+ end
125
+ end
126
+
127
+ RTM::AR.register_extension self
128
+ end
129
+ end
130
+
@@ -0,0 +1,162 @@
1
+ # Copyright: Copyright 2009 Topic Maps Lab, University of Leipzig.
2
+ # License: Apache License, Version 2.0
3
+
4
+ module RTM::AR::IO
5
+ # XTM1 Export
6
+ module TOXTM1
7
+ require 'rexml/document'
8
+ def self.scope(scope)
9
+ res = REXML::Element.new('scope')
10
+ scope.each do |s|
11
+ res << s.to_xtm_ref
12
+ end
13
+ res
14
+ end
15
+ def self.type(type)
16
+ res = REXML::Element.new('type')
17
+ res << type.to_xtm_ref
18
+ res
19
+ end
20
+ def self.value(datatype, value)
21
+ if datatype == RTM::PSI[:IRI]
22
+ res = REXML::Element.new 'resourceRef'
23
+ res.add_attribute('href', value)
24
+ else
25
+ res = REXML::Element.new 'resourceData'
26
+ res.add_attribute('datatype', datatype) if datatype
27
+ res.text = value
28
+ end
29
+ res
30
+ end
31
+ def self.locator(loc, tagname = "itemIdentity")
32
+ x = REXML::Element.new(tagname)
33
+ x.add_attribute('href',loc.to_s) # loc could be Locator or String, to_s serves both
34
+ x
35
+ end
36
+
37
+ module TopicMap
38
+ # returns the XTM 2.0 representation of this topic map as an REXML::Document, ready for outputting
39
+ def to_xtm1
40
+ # topicMap = element topicMap { reifiable, version, mergeMap*,
41
+ # (topic | association)* }
42
+ doc = REXML::Document.new
43
+ doc << REXML::XMLDecl.new
44
+ x = doc.add_element 'topicMap', {'xmlns' => 'http://www.topicmaps.org/xtm/', 'version' => '2.0'}
45
+ x.add_attribute('reifier', reifier.xtm1_id) if reifier
46
+ x << REXML::Comment.new("Topics count: #{topics.size}")
47
+ x << REXML::Comment.new("Associations count: #{associations.size}")
48
+ item_identifiers.each { |ii| x << TOXTM1.locator(ii) } # itemIdentity
49
+ # mergeMap not used
50
+ topics.each { |t| x << t.to_xtm1 }
51
+ associations.each { |a| x << a.to_xtm1 }
52
+ doc
53
+ x
54
+ end
55
+ end
56
+
57
+ module Topic
58
+ # this is a helper-method for the to_xtm1 amd to_xtm1_ref methods
59
+ def xtm1_id
60
+ "t#{id}"
61
+ end
62
+ # returns the XTM 2.0 representation of this topic as an REXML::Element
63
+ def to_xtm1
64
+ #topic = element topic { id,
65
+ # (itemIdentity | subjectLocator | subjectIdentifier)*,
66
+ # instanceOf?, (name | occurrence)* }
67
+ x = REXML::Element.new('topic')
68
+ x.add_attribute('id', xtm1_id )
69
+ item_identifiers.each { |ii| x << TOXTM1.locator(ii) } # itemIdentity
70
+ subject_identifiers.each { |si| x << TOXTM1.locator(si, "subjectIdentifier") } # subjectIdentifier
71
+ if item_identifiers.empty? && subject_identifiers.empty?
72
+ TOXTM1.locator(xtm1_id) # itemIdentity
73
+ end
74
+ subject_locators.each { |sl| x << TOXTM1.locator(sl, "subjectLocator") } # subjectLocator
75
+ # I guess we won't create instanceOf-Elements but instead type-instance associations.
76
+ names.each { |n| x << n.to_xtm1 }
77
+ occurrences.each { |o| x << o.to_xtm1 }
78
+ x
79
+ end
80
+ # returns the an (internal) XTM 2.0 reference to this topic
81
+ def to_xtm1_ref
82
+ x = REXML::Element.new 'topicRef'
83
+ x.add_attribute('href', "##{xtm1_id}")
84
+ x
85
+ end
86
+ end
87
+
88
+ module Association
89
+ # returns the XTM 2.0 representation of this association as an REXML::Element
90
+ def to_xtm1
91
+ warn("TOXTM1: Warning: outputting invalid Association #{self}") unless valid?
92
+ # association = element association { reifiable, type, scope?, role+ }
93
+ x = REXML::Element.new 'association'
94
+ x.add_attribute('reifier', reifier.xtm1_id) if reifier
95
+ item_identifiers.each { |ii| x << TOXTM1.ii(ii) } # itemIdentity
96
+ x << TOXTM1.type(type) if type
97
+ x << TOXTM1.scope(scope) unless scope.empty?
98
+ roles.each { |r| x << r.to_xtm1 }
99
+ x
100
+ end
101
+ end
102
+
103
+ module TopicName
104
+ def to_xtm1
105
+ warn("TOXTM1: Warning: outputting invalid TopicName #{self}") unless valid?
106
+ # name = element name { reifiable, type?, scope?, value, variant* }
107
+ x = REXML::Element.new 'name'
108
+ x.add_attribute('reifier', reifier.xtm1_id) if reifier
109
+ item_identifiers.each { |ii| x << TOXTM1.ii(ii) } # itemIdentity
110
+ x << TOXTM1.type(type) if type
111
+ x << TOXTM1.scope(scope) unless scope.empty?
112
+ (x << REXML::Element.new('value')).text = value # adds the value within a value-element
113
+ variants.each { |v| x << v.to_xtm1 }
114
+ x
115
+ end
116
+ end
117
+
118
+ module Occurrence
119
+ def to_xtm1
120
+ warn("TOXTM1: Warning: outputting invalid Occurrence #{self}") unless valid?
121
+ # occurrence = element occurrence { reifiable,
122
+ # type, scope?, ( resourceRef | resourceData ) }
123
+ x = REXML::Element.new 'occurrence'
124
+ x.add_attribute('reifier', reifier.xtm1_id) if reifier
125
+ item_identifiers.each { |ii| x << TOXTM1.ii(ii) } # itemIdentity
126
+ x << TOXTM1.type(type) if type
127
+ x << TOXTM1.scope(scope) unless scope.empty?
128
+ x << TOXTM1.value(datatype, value)
129
+ x
130
+ end
131
+ end
132
+
133
+ module AssociationRole
134
+ def to_xtm1
135
+ warn("TOXTM1: Warning: outputting invalid AssociationRole #{self}") unless valid?
136
+ # role = element role { reifiable, type, topicRef }
137
+ x = REXML::Element.new 'role'
138
+ x.add_attribute('reifier', reifier.xtm1_id) if reifier
139
+ item_identifiers.each { |ii| x << TOXTM1.ii(ii) } # itemIdentity
140
+ x << TOXTM1.type(type) if type
141
+ x << player.to_xtm1_ref if player
142
+ x
143
+ end
144
+ end
145
+
146
+ module Variant
147
+ def to_xtm1
148
+ warn("TOXTM1: Warning: outputting invalid Variant #{self}") unless valid?
149
+ # variant = element variant { reifiable, scope, (resourceRef | resourceData) }
150
+ x = REXML::Element.new 'variant'
151
+ x.add_attribute('reifier', reifier.xtm1_id) if reifier
152
+ item_identifiers.each { |ii| x << TOXTM1.ii(ii) } # itemIdentity
153
+ x << TOXTM1.scope(scope)
154
+ x << TOXTM1.value(datatype, value)
155
+ x
156
+ end
157
+ end
158
+
159
+ RTM::AR.register_extension self
160
+ end
161
+ end
162
+
@@ -0,0 +1,163 @@
1
+ # Copyright: Copyright 2009 Topic Maps Lab, University of Leipzig.
2
+ # License: Apache License, Version 2.0
3
+
4
+ module RTM::AR::IO
5
+ # XTM2 Export.
6
+ # Each Topic Maps Construct gets a to_xtm2 method.
7
+ # The result is a REXML::Element except for TopicMap where it is a REXML::Document.
8
+ module TOXTM2
9
+ require 'rexml/document'
10
+ def self.scope(scope)
11
+ res = REXML::Element.new('scope')
12
+ scope.each do |s|
13
+ res << s.to_xtm2_ref
14
+ end
15
+ res
16
+ end
17
+ def self.type(type)
18
+ res = REXML::Element.new('type')
19
+ res << type.to_xtm2_ref
20
+ res
21
+ end
22
+ def self.value(datatype, value)
23
+ if datatype == RTM::PSI[:IRI]
24
+ res = REXML::Element.new 'resourceRef'
25
+ res.add_attribute('href', value)
26
+ else
27
+ res = REXML::Element.new 'resourceData'
28
+ res.add_attribute('datatype', datatype) if datatype
29
+ res.text = value
30
+ end
31
+ res
32
+ end
33
+ def self.locator(loc, tagname = "itemIdentity")
34
+ x = REXML::Element.new(tagname)
35
+ x.add_attribute('href',loc.to_s) # loc could be Locator or String, to_s serves both
36
+ x
37
+ end
38
+
39
+ module TopicMap
40
+ # returns the XTM 2.0 representation of this topic map as an REXML::Document, ready for outputting
41
+ def to_xtm2
42
+ # topicMap = element topicMap { reifiable, version, mergeMap*,
43
+ # (topic | association)* }
44
+ doc = REXML::Document.new
45
+ doc << REXML::XMLDecl.new
46
+ x = doc.add_element 'topicMap', {'xmlns' => 'http://www.topicmaps.org/xtm/', 'version' => '2.0'}
47
+ x.add_attribute('reifier', reifier.xtm2_id) if reifier
48
+ x << REXML::Comment.new("Topics count: #{topics.size}")
49
+ x << REXML::Comment.new("Associations count: #{associations.size}")
50
+ item_identifiers.each { |ii| x << TOXTM2.locator(ii) } # itemIdentity
51
+ # mergeMap not used
52
+ topics.each { |t| x << t.to_xtm2 }
53
+ associations.each { |a| x << a.to_xtm2 }
54
+ doc
55
+ end
56
+ end
57
+
58
+ module Topic
59
+ # this is a helper-method for the to_xtm2 amd to_xtm2_ref methods
60
+ def xtm2_id
61
+ "t#{id}"
62
+ end
63
+ # returns the XTM 2.0 representation of this topic as an REXML::Element
64
+ def to_xtm2
65
+ #topic = element topic { id,
66
+ # (itemIdentity | subjectLocator | subjectIdentifier)*,
67
+ # instanceOf?, (name | occurrence)* }
68
+ x = REXML::Element.new('topic')
69
+ x.add_attribute('id', xtm2_id )
70
+ item_identifiers.each { |ii| x << TOXTM2.locator(ii) } # itemIdentity
71
+ subject_identifiers.each { |si| x << TOXTM2.locator(si, "subjectIdentifier") } # subjectIdentifier
72
+ if item_identifiers.empty? && subject_identifiers.empty?
73
+ TOXTM2.locator(xtm2_id) # itemIdentity
74
+ end
75
+ subject_locators.each { |sl| x << TOXTM2.locator(sl, "subjectLocator") } # subjectLocator
76
+ # I guess we won't create instanceOf-Elements but instead type-instance associations.
77
+ names.each { |n| x << n.to_xtm2 }
78
+ occurrences.each { |o| x << o.to_xtm2 }
79
+ x
80
+ end
81
+ # returns the an (internal) XTM 2.0 reference to this topic
82
+ def to_xtm2_ref
83
+ x = REXML::Element.new 'topicRef'
84
+ x.add_attribute('href', "##{xtm2_id}")
85
+ x
86
+ end
87
+ end
88
+
89
+ module Association
90
+ # returns the XTM 2.0 representation of this association as an REXML::Element
91
+ def to_xtm2
92
+ warn("TOXTM2: Warning: outputting invalid Association #{self}") unless valid?
93
+ # association = element association { reifiable, type, scope?, role+ }
94
+ x = REXML::Element.new 'association'
95
+ x.add_attribute('reifier', reifier.xtm2_id) if reifier
96
+ item_identifiers.each { |ii| x << TOXTM2.locator(ii) } # itemIdentity
97
+ x << TOXTM2.type(type) if type
98
+ x << TOXTM2.scope(scope) unless scope.empty?
99
+ roles.each { |r| x << r.to_xtm2 }
100
+ x
101
+ end
102
+ end
103
+
104
+ module TopicName
105
+ def to_xtm2
106
+ warn("TOXTM2: Warning: outputting invalid TopicName #{self}") unless valid?
107
+ # name = element name { reifiable, type?, scope?, value, variant* }
108
+ x = REXML::Element.new 'name'
109
+ x.add_attribute('reifier', reifier.xtm2_id) if reifier
110
+ item_identifiers.each { |ii| x << TOXTM2.locator(ii) } # itemIdentity
111
+ x << TOXTM2.type(type) if type
112
+ x << TOXTM2.scope(scope) unless scope.empty?
113
+ (x << REXML::Element.new('value')).text = value # adds the value within a value-element
114
+ variants.each { |v| x << v.to_xtm2 }
115
+ x
116
+ end
117
+ end
118
+
119
+ module Occurrence
120
+ def to_xtm2
121
+ warn("TOXTM2: Warning: outputting invalid Occurrence #{self}") unless valid?
122
+ # occurrence = element occurrence { reifiable,
123
+ # type, scope?, ( resourceRef | resourceData ) }
124
+ x = REXML::Element.new 'occurrence'
125
+ x.add_attribute('reifier', reifier.xtm2_id) if reifier
126
+ item_identifiers.each { |ii| x << TOXTM2.locator(ii) } # itemIdentity
127
+ x << TOXTM2.type(type) if type
128
+ x << TOXTM2.scope(scope) unless scope.empty?
129
+ x << TOXTM2.value(datatype, value)
130
+ x
131
+ end
132
+ end
133
+
134
+ module AssociationRole
135
+ def to_xtm2
136
+ warn("TOXTM2: Warning: outputting invalid AssociationRole #{self}") unless valid?
137
+ # role = element role { reifiable, type, topicRef }
138
+ x = REXML::Element.new 'role'
139
+ x.add_attribute('reifier', reifier.xtm2_id) if reifier
140
+ item_identifiers.each { |ii| x << TOXTM2.locator(ii) } # itemIdentity
141
+ x << TOXTM2.type(type) if type
142
+ x << player.to_xtm2_ref if player
143
+ x
144
+ end
145
+ end
146
+
147
+ module Variant
148
+ def to_xtm2
149
+ warn("TOXTM2: Warning: outputting invalid Variant #{self}") unless valid?
150
+ # variant = element variant { reifiable, scope, (resourceRef | resourceData) }
151
+ x = REXML::Element.new 'variant'
152
+ x.add_attribute('reifier', reifier.xtm2_id) if reifier
153
+ item_identifiers.each { |ii| x << TOXTM2.locator(ii) } # itemIdentity
154
+ x << TOXTM2.scope(scope)
155
+ x << TOXTM2.value(datatype, value)
156
+ x
157
+ end
158
+ end
159
+
160
+ RTM::AR.register_extension self
161
+ end
162
+ end
163
+