rtm 0.1.1 → 0.1.3
Sign up to get free protection for your applications and to get access to all the features.
- data/lib/activetopicmaps.rb +55 -6
- data/lib/rtm.rb +27 -8
- data/lib/rtm/backend/active_record.rb +29 -24
- data/lib/rtm/backend/active_record/association_and_role.rb +3 -24
- data/lib/rtm/backend/active_record/locators.rb +2 -0
- data/lib/rtm/backend/active_record/name_variant_occurrence.rb +5 -4
- data/lib/rtm/backend/active_record/tm_delegator.rb +0 -75
- data/lib/rtm/backend/active_record/tmdm.rb +5 -0
- data/lib/rtm/backend/active_record/topic.rb +10 -76
- data/lib/rtm/backend/active_record/topic_map.rb +30 -1
- data/lib/rtm/backend/active_record/traverse_associations.rb +86 -0
- data/lib/rtm/io/from_xtm2_libxml.rb +1 -1
- data/lib/rtm/locator_helpers.rb +16 -0
- data/lib/rtm/sugar/role/counterparts.rb +51 -0
- data/lib/rtm/sugar/topic/characteristics.rb +15 -0
- data/lib/rtm/sugar/topic/counterparts.rb +15 -0
- data/lib/rtm/sugar/topic/hash_access.rb +55 -0
- data/lib/rtm/sugar/topic/identifier_direct.rb +11 -0
- data/lib/rtm/sugar/topic/predefined_associations.rb +42 -0
- data/test/base_test.rb +153 -0
- metadata +84 -67
- data/lib/rtm/io/from_xtm2_jaxp.rb +0 -89
data/lib/activetopicmaps.rb
CHANGED
@@ -75,17 +75,30 @@ module ActiveTopicMaps
|
|
75
75
|
# EOS
|
76
76
|
# end
|
77
77
|
|
78
|
-
def name(name, type=
|
78
|
+
def name(name, type=nil)
|
79
|
+
type ||= name
|
79
80
|
prop_getter(name, type, "-")
|
80
81
|
prop_setter(name, type, "-")
|
81
82
|
end
|
82
|
-
|
83
|
+
|
84
|
+
def names(name, type=nil)
|
85
|
+
type ||= name.singularize
|
86
|
+
prop_getters(name, type, "-")
|
87
|
+
prop_adderremover(name, type, "-")
|
88
|
+
end
|
89
|
+
|
83
90
|
def occurrence(name, type=nil)
|
84
91
|
type ||= name
|
85
92
|
prop_getter(name, type)
|
86
93
|
prop_setter(name, type)
|
87
94
|
end
|
88
|
-
|
95
|
+
|
96
|
+
def occurrences(name, type=nil)
|
97
|
+
type ||= name.singularize
|
98
|
+
prop_getters(name, type)
|
99
|
+
prop_adderremover(name, type)
|
100
|
+
end
|
101
|
+
|
89
102
|
def prop_getter(name, type, prefix="")
|
90
103
|
self.class_eval <<-EOS
|
91
104
|
def #{name}
|
@@ -94,6 +107,14 @@ module ActiveTopicMaps
|
|
94
107
|
EOS
|
95
108
|
end
|
96
109
|
|
110
|
+
def prop_getters(name, type, prefix="")
|
111
|
+
self.class_eval <<-EOS
|
112
|
+
def #{name}
|
113
|
+
@#{name} ||= @topic["#{prefix}#{type}"].map{|n| n.value}
|
114
|
+
end
|
115
|
+
EOS
|
116
|
+
end
|
117
|
+
|
97
118
|
def prop_setter(name, type, prefix="")
|
98
119
|
self.class_eval <<-EOS
|
99
120
|
def #{name}=(name)
|
@@ -107,7 +128,18 @@ module ActiveTopicMaps
|
|
107
128
|
EOS
|
108
129
|
end
|
109
130
|
|
110
|
-
def
|
131
|
+
def prop_adderremover(name, type, prefix="")
|
132
|
+
self.class_eval <<-EOS
|
133
|
+
def add_#{name.singularize}(name)
|
134
|
+
@topic["#{prefix}#{type}"] = name
|
135
|
+
end
|
136
|
+
def remove_#{name.singularize}(name)
|
137
|
+
@topic["#{prefix}#{type}"].each {|item| item.remove if item.value == name}
|
138
|
+
end
|
139
|
+
EOS
|
140
|
+
end
|
141
|
+
|
142
|
+
def has_many(name, rt1, at, rt2, klass)
|
111
143
|
eval(<<-EOS)
|
112
144
|
class RTM::AR::Topic
|
113
145
|
index_property_set :#{name}, :type => :Topic, :rule => {
|
@@ -138,7 +170,12 @@ module ActiveTopicMaps
|
|
138
170
|
end
|
139
171
|
|
140
172
|
def create(ref)
|
141
|
-
|
173
|
+
t = @tm.get!(ref)
|
174
|
+
if @psi
|
175
|
+
@ty ||= @tm.get!(@psi)
|
176
|
+
t.add_type @ty unless t.types.include? @ty
|
177
|
+
end
|
178
|
+
self.new(t)
|
142
179
|
end
|
143
180
|
alias get! create
|
144
181
|
|
@@ -147,6 +184,16 @@ module ActiveTopicMaps
|
|
147
184
|
self.new(t) if t
|
148
185
|
end
|
149
186
|
alias get find
|
187
|
+
|
188
|
+
def find_by_type(ref=nil)
|
189
|
+
ref ||= @psi
|
190
|
+
ty = @tm.get(ref)
|
191
|
+
ty.instances.map {|t| self.new(t)}
|
192
|
+
end
|
193
|
+
|
194
|
+
def psi(ref)
|
195
|
+
@psi = ref
|
196
|
+
end
|
150
197
|
end
|
151
198
|
end
|
152
199
|
end
|
@@ -157,6 +204,7 @@ end
|
|
157
204
|
#
|
158
205
|
#class Person < ActiveTopicMaps::Base
|
159
206
|
# topic_map "urn:/base"
|
207
|
+
# psi "person"
|
160
208
|
#
|
161
209
|
# name :name
|
162
210
|
# occurrence :age
|
@@ -172,6 +220,7 @@ end
|
|
172
220
|
# include ActiveTopicMaps::Topic
|
173
221
|
#
|
174
222
|
# topic_map "urn:/base"
|
223
|
+
# psi "country"
|
175
224
|
#
|
176
225
|
# acts_as_topic
|
177
226
|
#
|
@@ -179,7 +228,7 @@ end
|
|
179
228
|
# occurrence :population
|
180
229
|
# occurrence :size
|
181
230
|
#
|
182
|
-
#
|
231
|
+
# has_many :inhabitants, "country", "country-inhabitant", "inhabitant", :Person
|
183
232
|
#
|
184
233
|
# def to_s
|
185
234
|
# "There is a country called #{name} with #{population} inhabitants and a size of #{size} km^2.\n" +
|
data/lib/rtm.rb
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
# RTM: Ruby Topic Maps.
|
2
|
-
# Copyright (c) 2007 Benjamin Bock.
|
2
|
+
# Copyright (c) 2007-2008 Benjamin Bock.
|
3
3
|
# All rights reserved.
|
4
4
|
#
|
5
5
|
# Redistribution and use in source and binary forms, with or without
|
@@ -35,12 +35,27 @@
|
|
35
35
|
module RTM
|
36
36
|
|
37
37
|
end
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
38
|
+
|
39
|
+
$:.unshift(File.dirname(__FILE__)) unless
|
40
|
+
$:.include?(File.dirname(__FILE__)) || $:.include?(File.expand_path(File.dirname(__FILE__)))
|
41
|
+
|
42
|
+
unless defined? ActiveRecord
|
43
|
+
active_record_path = File.dirname(__FILE__) + "/../../activerecord/lib"
|
44
|
+
if File.exist?(active_record_path)
|
45
|
+
$:.unshift active_record_path
|
46
|
+
old_verbose=$VERBOSE
|
47
|
+
$VERBOSE=false
|
48
|
+
require 'active_record'
|
49
|
+
$VERBOSE=old_verbose
|
50
|
+
else
|
51
|
+
require 'rubygems'
|
52
|
+
gem 'activerecord'
|
53
|
+
old_verbose=$VERBOSE
|
54
|
+
$VERBOSE=false
|
55
|
+
require 'active_record'
|
56
|
+
$VERBOSE=old_verbose
|
57
|
+
end
|
58
|
+
end
|
44
59
|
|
45
60
|
require 'rtm/core_ext'
|
46
61
|
require 'rtm/helpers'
|
@@ -54,7 +69,11 @@ require 'rtm/io/to_string'
|
|
54
69
|
require 'rtm/io/to_xtm2'
|
55
70
|
require 'rtm/io/to_yaml'
|
56
71
|
require 'rtm/io/from_xtm2'
|
57
|
-
|
72
|
+
begin
|
73
|
+
require 'rtm/io/from_xtm2_libxml.rb'
|
74
|
+
rescue Exception
|
75
|
+
warn("LibXML could not be loaded, only (slow) REXML import available")
|
76
|
+
end
|
58
77
|
#require 'rtm/io/from_xtm2_hpricot'
|
59
78
|
require 'rtm/merging/merging'
|
60
79
|
require 'rtm/pimp_my_api'
|
@@ -5,30 +5,34 @@ class Class
|
|
5
5
|
rtm_old_const_missing(const_name)
|
6
6
|
end
|
7
7
|
end
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
end
|
31
|
-
|
8
|
+
# The following methods allow automatic +map+ping on arrays to their containees properties.
|
9
|
+
# However this is a dirt hack and did no longer work in ActiveRecord 2.1.0.
|
10
|
+
# This should be fixed some time later.
|
11
|
+
#
|
12
|
+
#class Array
|
13
|
+
# alias :rtm_old_method_missing :method_missing
|
14
|
+
# def method_missing(method_name, *args)
|
15
|
+
# if size > 0 && first.respond_to?(method_name) && (![:__getobj__, :__setobj__].include?(method_name))
|
16
|
+
# inject([]) {|all,single| all << single.send(method_name, *args)}
|
17
|
+
# else
|
18
|
+
# rtm_old_method_missing(method_name, *args)
|
19
|
+
# end
|
20
|
+
# end
|
21
|
+
#
|
22
|
+
# alias :rtm_old_respond_to? :respond_to?
|
23
|
+
# def respond_to?(method_name, *args)
|
24
|
+
# resp = rtm_old_respond_to?(method_name, *args)
|
25
|
+
# return resp if resp # i.e. if true
|
26
|
+
# # check for special calls we don't want to pass
|
27
|
+
# return false if [:__getobj__, :__setobj__].include?(method_name)
|
28
|
+
# # ... and ask first child otherwise
|
29
|
+
# @obj && @obj.size > 0 && first.respond_to?(method_name, *args)
|
30
|
+
# end
|
31
|
+
#
|
32
|
+
# def compact_empty
|
33
|
+
# compact.reject{|e| e.empty?}
|
34
|
+
# end
|
35
|
+
#end
|
32
36
|
class ActiveRecord::Associations::AssociationProxy
|
33
37
|
# this is needed to prevent the associations from being instantly loaded
|
34
38
|
alias :rtm_old_respond_to? :respond_to?
|
@@ -45,6 +49,7 @@ module RTM::AR
|
|
45
49
|
require 'rtm/backend/active_record/tm_set_delegator'
|
46
50
|
require 'rtm/backend/active_record/tm_construct'
|
47
51
|
require 'rtm/backend/active_record/topic_map'
|
52
|
+
require 'rtm/backend/active_record/traverse_associations'
|
48
53
|
require 'rtm/backend/active_record/topic'
|
49
54
|
require 'rtm/backend/active_record/association_and_role'
|
50
55
|
require 'rtm/backend/active_record/name_variant_occurrence'
|
@@ -24,31 +24,10 @@ module RTM::AR
|
|
24
24
|
property :player, :aka => [:pl,:topic], :rw => true, :type => :Topic, :wrap => true
|
25
25
|
property :type, :aka => [:ty,:t], :rw => true, :type => :Topic, :wrap => true
|
26
26
|
|
27
|
-
|
28
|
-
|
29
|
-
end
|
30
|
-
def counterplayers
|
31
|
-
self.counterparts.map{|r| r.player}
|
32
|
-
end
|
33
|
-
def counterpart
|
34
|
-
n = self.parent.roles.size
|
35
|
-
raise "Association must be unary or binary to use counterpart method. Please use counterparts for n-ary associations." if n > 2
|
36
|
-
return nil if n == 1
|
37
|
-
self.parent.roles.reject{|r| r.id==self.id}.first
|
38
|
-
end
|
39
|
-
def counterplayer
|
40
|
-
n = self.parent.roles.size
|
41
|
-
raise "Association must be unary or binary to use counterplayer method. Please use counterplayers for n-ary associations." if n > 2
|
42
|
-
return nil if n == 1
|
43
|
-
self.parent.roles.reject{|r| r.id==self.id}.first.player
|
44
|
-
end
|
45
|
-
def peers
|
46
|
-
self.counterpart.player.roles.select{|r| r.type == cp.type}.counterpart
|
47
|
-
end
|
48
|
-
def peerplayers
|
49
|
-
self.peers.map{|r| r.player}
|
50
|
-
end
|
27
|
+
require 'rtm/sugar/role/counterparts'
|
28
|
+
include RTM::Sugar::Role::Counterparts
|
51
29
|
|
52
30
|
equality [:type, :player, :parent]
|
53
31
|
end
|
32
|
+
Role = AssociationRole
|
54
33
|
end
|
@@ -7,21 +7,22 @@ module RTM::AR
|
|
7
7
|
property :type, :aka => [:ty,:t], :rw => true, :type => :Topic, :wrap => true
|
8
8
|
property_set :scope, :type => :Topic, :wrap => true
|
9
9
|
|
10
|
-
property_set :variants, :aka => :
|
10
|
+
property_set :variants, :aka => :vs, :type => :Variant, :wrap => true,
|
11
11
|
:create => :variant, :create_aka => :cv,
|
12
12
|
:create_args => [ {:name => :value, :type => [:String, :Locator]}, {:name => :scope, :type => :Collection}]
|
13
13
|
|
14
|
-
property :value, :rw => true, :type => :String
|
14
|
+
property :value, :rw => true, :type => :String, :aka => :v
|
15
15
|
|
16
16
|
equality [:value, :type, :scope, :parent]
|
17
17
|
end
|
18
|
+
Name = TopicName
|
18
19
|
|
19
20
|
class Variant < Reifiable
|
20
21
|
include RTM::Variant
|
21
22
|
wrapper_cache
|
22
23
|
|
23
24
|
parent :topic_name, :aka => :name
|
24
|
-
property :value, :rw => true, :type => :String
|
25
|
+
property :value, :rw => true, :type => :String, :aka => :v
|
25
26
|
property :datatype, :rw => true, :type => :Locator #, :wrap => true
|
26
27
|
property_set :scope, :type => :Topic, :wrap => true
|
27
28
|
|
@@ -33,7 +34,7 @@ module RTM::AR
|
|
33
34
|
wrapper_cache
|
34
35
|
|
35
36
|
parent :topic
|
36
|
-
property :value, :rw => true, :type => :String
|
37
|
+
property :value, :rw => true, :type => :String, :aka => :v
|
37
38
|
property :datatype, :rw => true, :type => :String
|
38
39
|
|
39
40
|
property_set :scope, :type => :Topic, :wrap => true
|
@@ -291,81 +291,6 @@ RUBY
|
|
291
291
|
end
|
292
292
|
end
|
293
293
|
|
294
|
-
def self.index_property_set(prop, options={})
|
295
|
-
r = options[:rule]
|
296
|
-
module_eval(<<-EOS, "(__AR_DELEGATOR_INDEX_PROPERTY_SET__)", 1)
|
297
|
-
def direct_#{prop}_roles
|
298
|
-
# prefetch typing topics
|
299
|
-
rtype = @ips_#{prop}_rtype ||= self.topic_map.get("#{r[:role_type]}")
|
300
|
-
atype = @ips_#{prop}_atype ||= self.topic_map.get("#{r[:association_type]}")
|
301
|
-
otype = @ips_#{prop}_otype ||= self.topic_map.get("#{r[:other_role_type]}")
|
302
|
-
# return nothing if any of the typing topics does not exist
|
303
|
-
return [] unless rtype && atype && otype
|
304
|
-
# we do that only here and not earlier because some might me nil
|
305
|
-
rtype = rtype.id
|
306
|
-
atype = atype.id
|
307
|
-
otype = otype.id
|
308
|
-
self.__getobj__.roles.map{|r|
|
309
|
-
r.ttype_id != nil &&
|
310
|
-
r.ttype_id == rtype &&
|
311
|
-
r.parent.roles.size == #{r[:association_arity]} &&
|
312
|
-
r.parent != nil &&
|
313
|
-
r.parent.ttype_id == atype &&
|
314
|
-
(r2 = r.parent.roles.select{|r2| r2.ttype_id != nil &&
|
315
|
-
r2.ttype_id == otype}.first) &&
|
316
|
-
r2}.select{|r2| r2}.map{|r2| AssociationRole.wrap(r2)}
|
317
|
-
end
|
318
|
-
def direct_#{prop}
|
319
|
-
direct_#{prop}_roles.map{|r2| r2.player}.uniq
|
320
|
-
end
|
321
|
-
EOS
|
322
|
-
|
323
|
-
if r[:transitive]
|
324
|
-
module_eval(<<-EOS, "(__AR_DELEGATOR_INDEX_PROPERTY_SET2__)", 1)
|
325
|
-
def #{prop}
|
326
|
-
d = todo = self.direct_#{prop}
|
327
|
-
while todo.size > 0
|
328
|
-
todo = todo.map{|dt| dt.direct_#{prop}}.flatten.uniq - d
|
329
|
-
d += todo
|
330
|
-
end
|
331
|
-
d
|
332
|
-
#d2 = self.direct_#{prop}.map {|dt| dt.#{prop}}.flatten
|
333
|
-
#(d+d2).uniq
|
334
|
-
end
|
335
|
-
EOS
|
336
|
-
else
|
337
|
-
if r[:infer]
|
338
|
-
module_eval(<<-EOS, "(__AR_DELEGATOR_INDEX_PROPERTY_SET3__)", 1)
|
339
|
-
def #{prop}
|
340
|
-
(self.direct_#{prop} + self.#{r[:infer]}.map{|d2| d2.direct_#{prop}}).flatten.uniq
|
341
|
-
end
|
342
|
-
EOS
|
343
|
-
elsif r[:infer_other]
|
344
|
-
module_eval(<<-EOS, "(__AR_DELEGATOR_INDEX_PROPERTY_SET4__)", 1)
|
345
|
-
def #{prop}
|
346
|
-
d = self.direct_#{prop}
|
347
|
-
(d + d.map{|d2| d2.#{r[:infer_other]}}).flatten.uniq
|
348
|
-
end
|
349
|
-
EOS
|
350
|
-
end
|
351
|
-
end
|
352
|
-
if r[:add]
|
353
|
-
module_eval(<<-EOS, "(__AR_DELEGATOR_INDEX_PROPERTY_SET5__)", 1)
|
354
|
-
def add_#{r[:add]}(t)
|
355
|
-
a = self.topic_map.create_association("#{r[:association_type]}")
|
356
|
-
a.create_role self, "#{r[:role_type]}"
|
357
|
-
a.create_role t, "#{r[:other_role_type]}"
|
358
|
-
a
|
359
|
-
# TODO add_x in index_property_set needs to trigger reload of the topics somewhere
|
360
|
-
end
|
361
|
-
def remove_#{r[:add]}(t)
|
362
|
-
direct_#{prop}_roles.select{|r| r.player == t}.each{|r| r.parent.remove}
|
363
|
-
# TODO remove_x in index_property_set needs to trigger reload of the topics somewhere
|
364
|
-
end
|
365
|
-
EOS
|
366
|
-
end
|
367
|
-
end
|
368
|
-
|
369
294
|
def self.equality(eqfields, options={})
|
370
295
|
field_condition = eqfields.map {|f| "self.#{f} == o.#{f}" }.join(" && ")
|
371
296
|
module_eval(<<-EOS, "(__AR_EQUALITY__)", 1)
|
@@ -36,6 +36,7 @@ module RTM::AR
|
|
36
36
|
end
|
37
37
|
|
38
38
|
class TopicMapConstruct < ActiveRecord::Base
|
39
|
+
self.store_full_sti_class = false
|
39
40
|
extend Movable
|
40
41
|
class << self
|
41
42
|
def abstract_class?
|
@@ -108,6 +109,7 @@ module RTM::AR
|
|
108
109
|
# end
|
109
110
|
end
|
110
111
|
class ScopedObjectsTopic < ActiveRecord::Base
|
112
|
+
self.store_full_sti_class = false
|
111
113
|
extend Movable
|
112
114
|
belongs_to :topic
|
113
115
|
belongs_to :scoped_object, :polymorphic => true
|
@@ -118,6 +120,7 @@ module RTM::AR
|
|
118
120
|
end
|
119
121
|
|
120
122
|
class Locator < ActiveRecord::Base
|
123
|
+
self.store_full_sti_class = false
|
121
124
|
extend Movable
|
122
125
|
class << self
|
123
126
|
def abstract_class?
|
@@ -253,8 +256,10 @@ module RTM::AR
|
|
253
256
|
has_many :subject_identifiers, :dependent => :destroy
|
254
257
|
|
255
258
|
has_many :topic_names, :through => :topics
|
259
|
+
alias :names :topic_names
|
256
260
|
has_many :occurrences, :through => :topics
|
257
261
|
has_many :association_roles, :through => :associations
|
262
|
+
alias :roles :association_roles
|
258
263
|
|
259
264
|
%w[association association_role topic_name occurrence].each do |m|
|
260
265
|
module_eval(<<-EOS, "(__AR_DELEGATOR_INDEX_PROPERTY_SET__)", 1)
|
@@ -23,16 +23,6 @@ module RTM::AR
|
|
23
23
|
:create => :occurrence, :create_aka => :co,
|
24
24
|
:create_args => [ {:name => :value, :type => [:String, :Locator]}, {:name => :type, :type => :Topic}, {:name => :scope, :type => :Collection} ]
|
25
25
|
|
26
|
-
def characteristics
|
27
|
-
topic_names.to_a + occurrences.to_a
|
28
|
-
end
|
29
|
-
def internal_occurrences
|
30
|
-
occurrences.select{|o| o.datatype != RTM::PSI[:IRI]}
|
31
|
-
end
|
32
|
-
def external_occurrences
|
33
|
-
occurrences.select{|o| o.datatype == RTM::PSI[:IRI]}
|
34
|
-
end
|
35
|
-
|
36
26
|
property_set :roles, :aka => [:r, :roles_played, :association_roles], :computable => true, :type => :AssociationRole, :wrap => true
|
37
27
|
|
38
28
|
property_set :associations, :aka => [:a, :associations_played], :type => :Association, :wrap => true
|
@@ -48,72 +38,16 @@ module RTM::AR
|
|
48
38
|
property_set :topic_names_typed, :aka => [:names_typed,:tnt,:nt], :type => :TopicName, :wrap => true
|
49
39
|
property_set :occurrences_typed, :aka => :ot, :type => :Occurrence, :wrap => true
|
50
40
|
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
index_property_set :instances, :type => :Topic, :rule => {
|
62
|
-
:transitive => false,
|
63
|
-
:role_type => RTM::PSI[:type],
|
64
|
-
:association_type => RTM::PSI[:type_instance],
|
65
|
-
:association_arity => 2,
|
66
|
-
:other_role_type => RTM::PSI[:instance],
|
67
|
-
:infer => :subtypes,
|
68
|
-
:add => :instance,
|
69
|
-
}
|
70
|
-
index_property_set :supertypes, :type => :Topic, :rule => {
|
71
|
-
:transitive => true,
|
72
|
-
:role_type => RTM::PSI[:subtype],
|
73
|
-
:association_type => RTM::PSI[:supertype_subtype],
|
74
|
-
:association_arity => 2,
|
75
|
-
:other_role_type => RTM::PSI[:supertype],
|
76
|
-
:add => :supertype,
|
77
|
-
}
|
78
|
-
index_property_set :subtypes, :type => :Topic, :rule => {
|
79
|
-
:transitive => true,
|
80
|
-
:role_type => RTM::PSI[:supertype],
|
81
|
-
:association_type => RTM::PSI[:supertype_subtype],
|
82
|
-
:association_arity => 2,
|
83
|
-
:other_role_type => RTM::PSI[:subtype],
|
84
|
-
:add => :subtype,
|
85
|
-
}
|
86
|
-
|
87
|
-
def [](topicref)
|
88
|
-
topicref =~ /^(-\s*)?(.+)?$/
|
89
|
-
if $1
|
90
|
-
nametype = $2 || RTM::PSI[:name_type]
|
91
|
-
names.select{|n| n.type == topic_map.get(nametype)}
|
92
|
-
else
|
93
|
-
raise "No occurrence type given" unless $2 and !$2.empty?
|
94
|
-
occurrences.select{|o| o.type == topic_map.get($2)}
|
95
|
-
end
|
96
|
-
end
|
97
|
-
|
98
|
-
def []=(topicref, value)
|
99
|
-
topicref =~ /^(-\s*)?(.+)?$/
|
100
|
-
if $1
|
101
|
-
nametype = $2 || topic_map.get!(RTM::PSI[:name_type])
|
102
|
-
n = create_name(value, nametype)
|
103
|
-
n
|
104
|
-
else
|
105
|
-
raise "No occurrence type given" unless $2
|
106
|
-
o = create_occurrence(value, $2)
|
107
|
-
o
|
108
|
-
end
|
109
|
-
end
|
110
|
-
|
111
|
-
def counterparts
|
112
|
-
self.roles.map{|sr| sr.parent.roles.reject{|r| r.id==sr.id}}
|
113
|
-
end
|
114
|
-
def counterplayers
|
115
|
-
self.counterparts.map{|r| r.player}
|
116
|
-
end
|
41
|
+
require 'rtm/sugar/topic/characteristics'
|
42
|
+
include RTM::Sugar::Topic::Characteristics
|
43
|
+
require 'rtm/sugar/topic/counterparts'
|
44
|
+
include RTM::Sugar::Topic::Counterparts
|
45
|
+
require 'rtm/sugar/topic/identifier_direct'
|
46
|
+
include RTM::Sugar::Topic::IdentifierDirect
|
47
|
+
require 'rtm/sugar/topic/hash_access'
|
48
|
+
include RTM::Sugar::Topic::HashAccess
|
49
|
+
require 'rtm/sugar/topic/predefined_associations'
|
50
|
+
include RTM::Sugar::Topic::PredefinedAssociations
|
117
51
|
|
118
52
|
# class:Topic equality, http://www.isotopicmaps.org/sam/sam-model/#d0e1029
|
119
53
|
#
|