rtm-activerecord 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
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
+