rtm 0.2.0 → 0.2.1
Sign up to get free protection for your applications and to get access to all the features.
- data/README +38 -3
- data/lib/rtm.rb +25 -47
- data/lib/rtm/axes.rb +7 -4
- data/lib/rtm/axes/association.rb +1 -1
- data/lib/rtm/axes/associations.rb +1 -1
- data/lib/rtm/axes/characteristic.rb +1 -1
- data/lib/rtm/axes/characteristics.rb +1 -1
- data/lib/rtm/axes/topic.rb +3 -3
- data/lib/rtm/axes/topics.rb +3 -3
- data/lib/rtm/engine.rb +48 -5
- data/lib/rtm/extensions.rb +58 -8
- data/lib/rtm/io.rb +2 -1
- data/lib/rtm/io/tmapix_from.rb +155 -0
- data/lib/rtm/io/tmapix_to.rb +223 -0
- data/lib/rtm/io/to_hash.rb +79 -41
- data/lib/rtm/io/to_jtm.rb +1 -1
- data/lib/rtm/io/to_rdf.rb +20 -5
- data/lib/rtm/io/to_string.rb +13 -2
- data/lib/rtm/io/to_yaml.rb +39 -11
- data/lib/rtm/navigation.rb +1 -15
- data/lib/rtm/navigation/association/players.rb +1 -1
- data/lib/rtm/navigation/name/characteristics.rb +1 -1
- data/lib/rtm/navigation/occurrence/characteristics.rb +1 -1
- data/lib/rtm/navigation/topic/characteristics.rb +1 -1
- data/lib/rtm/navigation/topic/players.rb +1 -1
- data/lib/rtm/navigation/topic/supertypes.rb +21 -17
- data/lib/rtm/navigation/topic/traverse.rb +1 -1
- data/lib/rtm/navigation/topic/types.rb +6 -4
- data/lib/rtm/psi.rb +6 -0
- data/lib/rtm/sugar.rb +42 -29
- data/lib/rtm/sugar/association/hash_access.rb +3 -3
- data/lib/rtm/sugar/occurrence/dynamic_value.rb +39 -56
- data/lib/rtm/sugar/occurrence/external.rb +53 -0
- data/lib/rtm/sugar/reifiable/reifier.rb +21 -0
- data/lib/rtm/sugar/role/counterparts.rb +12 -6
- data/lib/rtm/sugar/topic/best_name.rb +74 -0
- data/lib/rtm/sugar/topic/characteristics.rb +10 -10
- data/lib/rtm/sugar/topic/counterparts.rb +131 -119
- data/lib/rtm/sugar/topic/scoped.rb +102 -53
- data/lib/rtm/sugar/topic/topic_ref.rb +63 -12
- data/lib/rtm/sugar/topic/typed.rb +50 -2
- data/lib/rtm/sugar/topic_map/query_cache.rb +66 -0
- data/lib/rtm/sugar/topic_map/themes.rb +53 -0
- data/lib/rtm/sugar/typed/types.rb +1 -1
- data/lib/rtm/validation.rb +2 -2
- data/lib/rtm/version.rb +18 -6
- data/spec/rtm/axes/string_spec.rb +7 -7
- data/spec/rtm/axes/strings_spec.rb +10 -10
- data/spec/rtm/io/tmapix_from_spec.rb +76 -0
- data/spec/rtm/io/tmapix_to_spec.rb +159 -0
- data/spec/rtm/io/to_hash_spec.rb +90 -0
- data/spec/rtm/io/to_rdf_spec.rb +37 -0
- data/spec/rtm/io/to_string_spec.rb +122 -0
- data/spec/rtm/io/to_yaml_spec.rb +89 -0
- data/spec/rtm/sugar/occurrence/dynamic_value_spec.rb +156 -1
- data/spec/rtm/sugar/occurrence/external_spec.rb +129 -0
- data/spec/rtm/sugar/reifiable/reifier_spec.rb +41 -0
- data/spec/rtm/sugar/role/counterparts_spec.rb +174 -172
- data/spec/rtm/sugar/topic/best_name_spec.rb +25 -0
- data/spec/rtm/sugar/topic/characteristics_spec.rb +20 -5
- data/spec/rtm/sugar/topic/counterparts_spec.rb +41 -1
- data/spec/rtm/sugar/topic/hash_access_spec.rb +1 -1
- data/spec/rtm/sugar/topic/scoped_spec.rb +178 -114
- data/spec/rtm/sugar/topic/topic_ref_spec.rb +10 -10
- data/spec/rtm/sugar/topic/typed_spec.rb +196 -134
- data/spec/rtm/sugar/topic_map/themes_spec.rb +67 -0
- data/spec/rtm/sugar/typed/types_spec.rb +1 -1
- data/spec/rtm/tmapi/core/association_spec.rb +2 -2
- data/spec/rtm/tmapi/core/datatype_aware_spec.rb +236 -0
- data/spec/rtm/tmapi/core/name_spec.rb +186 -1
- data/spec/rtm/tmapi/core/occurrence_spec.rb +24 -67
- data/spec/rtm/tmapi/core/reifiable_spec.rb +2 -2
- data/spec/rtm/tmapi/core/scoped_spec.rb +40 -2
- data/spec/rtm/tmapi/core/topic_map_spec.rb +98 -30
- data/spec/rtm/tmapi/core/topic_spec.rb +558 -82
- data/spec/rtm/tmapi/core/variant_spec.rb +3 -3
- data/spec/rtm_spec.rb +0 -1
- data/spec/spec_helper.rb +7 -2
- data/test/javalibs/junit-4.5.jar +0 -0
- data/test/javalibs/tmapi-2.0-tests.jar +0 -0
- data/test/tmapi_tests.rb +25 -0
- metadata +66 -11
- data/lib/rtm/io/ontopia_io.rb +0 -25
- data/lib/rtm/io/tmapix.rb +0 -234
- data/lib/rtm/sugar/occurrence/externalize.rb +0 -31
- data/spec/rtm/io/tmapix_spec.rb +0 -85
- data/test/base_unit_test.rb +0 -161
- data/test/base_unit_test_tmapi.rb +0 -165
@@ -1,7 +1,7 @@
|
|
1
1
|
# Copyright: Copyright 2009 Topic Maps Lab, University of Leipzig.
|
2
2
|
# License: Apache License, Version 2.0
|
3
3
|
|
4
|
-
module Sugar
|
4
|
+
module RTM::Sugar
|
5
5
|
module Association
|
6
6
|
# This module implements methods for Hash-like access in Associations.
|
7
7
|
module HashAccess
|
@@ -10,7 +10,7 @@ module Sugar
|
|
10
10
|
#
|
11
11
|
# If type is given, returns the Roles of this Association
|
12
12
|
# whose Role type match type.
|
13
|
-
# Type may be a
|
13
|
+
# Type may be a topic reference.
|
14
14
|
#
|
15
15
|
# The result may be empty.
|
16
16
|
#
|
@@ -32,7 +32,7 @@ module Sugar
|
|
32
32
|
|
33
33
|
# Creates a new Role in this Association where type specifies the
|
34
34
|
# Role type and player the associated Role player.
|
35
|
-
# Type and player may each be a
|
35
|
+
# Type and player may each be a topic reference.
|
36
36
|
#
|
37
37
|
# :call-seq:
|
38
38
|
# [type]= player
|
@@ -1,34 +1,43 @@
|
|
1
1
|
# Copyright: Copyright 2010 Topic Maps Lab, University of Leipzig.
|
2
2
|
# License: Apache License, Version 2.0
|
3
3
|
|
4
|
-
module Sugar::Occurrence
|
4
|
+
module RTM::Sugar::Occurrence
|
5
5
|
module DynamicValue
|
6
|
-
|
6
|
+
|
7
|
+
# Given the occurrence's datatype this method returns the value of this
|
8
|
+
# occurrence cast as appropriate Ruby type.
|
9
|
+
#
|
10
|
+
# :call-seq:
|
11
|
+
# dynamic_value -> Object
|
12
|
+
#
|
7
13
|
def dynamic_value
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
14
|
+
value = self.value # a String
|
15
|
+
case self.datatype.reference
|
16
|
+
when RTM::PSI[:IRI]
|
17
|
+
return topic_map.create_locator(value)
|
18
|
+
when RTM::PSI[:Decimal]
|
19
|
+
return value.to_f
|
20
|
+
when RTM::PSI[:Double]
|
21
|
+
return value.to_f
|
22
|
+
when RTM::PSI[:Int]
|
23
|
+
return value.to_i
|
24
|
+
when RTM::PSI[:Integer]
|
25
|
+
return value.to_i
|
26
|
+
when RTM::PSI[:Float]
|
27
|
+
return value.to_f
|
28
|
+
when RTM::PSI[:Long]
|
29
|
+
return value.to_i
|
30
|
+
when RTM::PSI[:Date]
|
31
|
+
return Date.parse(value)
|
32
|
+
when RTM::PSI[:DateTime]
|
33
|
+
return DateTime.parse(value)
|
34
|
+
when RTM::PSI[:Time]
|
35
|
+
return Time.parse(value)
|
36
|
+
else
|
37
|
+
return value
|
30
38
|
end
|
31
39
|
end
|
40
|
+
|
32
41
|
end
|
33
42
|
end
|
34
43
|
|
@@ -37,39 +46,13 @@ class Float
|
|
37
46
|
s = self.to_s
|
38
47
|
|
39
48
|
case s
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
49
|
+
when "Infinity"
|
50
|
+
"INF"
|
51
|
+
when "-Infinity"
|
52
|
+
"-INF"
|
53
|
+
else
|
54
|
+
s
|
46
55
|
end
|
47
56
|
end
|
48
57
|
end
|
49
58
|
|
50
|
-
module Sugar::Topic::Characteristics
|
51
|
-
#
|
52
|
-
# Weird. create_occurrence has an options hash, and we don't have one. We should unify the syntax. What is the right thing to do?
|
53
|
-
#
|
54
|
-
def dynamic_create_occurrence(type,value,datatype,scope = nil)
|
55
|
-
if !datatype # well, let's choose one
|
56
|
-
case value
|
57
|
-
when Integer
|
58
|
-
datatype = RTM::PSI[:Integer]
|
59
|
-
use_value = value.to_s
|
60
|
-
when Float
|
61
|
-
datatype = RTM::PSI[:Double]
|
62
|
-
use_value = value.to_xsd_double
|
63
|
-
when String
|
64
|
-
datatype = RTM::PSI[:String]
|
65
|
-
use_value = value
|
66
|
-
else
|
67
|
-
raise Sugar::Occurrence::DynamicValue::NoDatatypeHandlerAvailableException.new(value)
|
68
|
-
end
|
69
|
-
else
|
70
|
-
use_value = value
|
71
|
-
end
|
72
|
-
|
73
|
-
create_occurrence(type,use_value,:datatype => datatype, :scope => scope)
|
74
|
-
end
|
75
|
-
end
|
@@ -0,0 +1,53 @@
|
|
1
|
+
# Copyright: Copyright 2009 Topic Maps Lab, University of Leipzig.
|
2
|
+
# License: Apache License, Version 2.0
|
3
|
+
|
4
|
+
module RTM::Sugar::Occurrence
|
5
|
+
module External
|
6
|
+
|
7
|
+
# Creates an association out of this occurrence which represents the
|
8
|
+
# occurrence information in relation to the parent topic.
|
9
|
+
#
|
10
|
+
# The association is of type "http://psi.topicmapslab.de/subject-representation".
|
11
|
+
# It includes two roles. The parent topic plays the role of type
|
12
|
+
# "http://psi.topicmapslab.de/represented-subject". The topic with the
|
13
|
+
# subject locator created from the occurrence value plays the role
|
14
|
+
# of a type the same as the occurrence type.
|
15
|
+
#
|
16
|
+
# The subject locator will be resolved using the get-method of RTM::TopicMap,
|
17
|
+
# that means if the occurrence value is stored as String and is not a valid uri
|
18
|
+
# the base_iri of the topic map is used to create one.
|
19
|
+
#
|
20
|
+
# The occurrence datatype may be xsd:anyURI as well as xsd:String.
|
21
|
+
# The occurrence value must be a valid URL.
|
22
|
+
#
|
23
|
+
# Example: Creates an association out of the occurrence with value
|
24
|
+
# "http://www.leipzig.de" and type "webpage" of the topic Leipzig:
|
25
|
+
# * association type: subject_representation
|
26
|
+
# * role 1: Leipzig plays the role "represented_subject"
|
27
|
+
# * role 2: topic with subject locator "http://www.leipzig.de" plays the role "webpage"
|
28
|
+
#
|
29
|
+
# :call-seq:
|
30
|
+
# externalize -> Association
|
31
|
+
#
|
32
|
+
def externalize
|
33
|
+
topic_map.create_association(RTM::PSI[:subject_representation], RTM::PSI[:represented_subject] => parent, self.type => "=#{self.value}")
|
34
|
+
end
|
35
|
+
|
36
|
+
# Executes externalize and removes this occurrence from the topic map afterwards
|
37
|
+
#
|
38
|
+
# :call-seq:
|
39
|
+
# externalize!
|
40
|
+
#
|
41
|
+
def externalize!(*args)
|
42
|
+
association = externalize(*args)
|
43
|
+
remove
|
44
|
+
return association
|
45
|
+
end
|
46
|
+
|
47
|
+
# Returns true, if the datatype of this occurrence equals xsd:anyURI.
|
48
|
+
def external?
|
49
|
+
return self.datatype.reference == RTM::PSI[:IRI] ? true : false
|
50
|
+
end
|
51
|
+
|
52
|
+
end
|
53
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
# Copyright: Copyright 2009 Topic Maps Lab, University of Leipzig.
|
2
|
+
# License: Apache License, Version 2.0
|
3
|
+
|
4
|
+
module RTM::Sugar::Reifiable
|
5
|
+
module CreateReifier
|
6
|
+
|
7
|
+
# Returns the reifier (a topic) of this Reifiable.
|
8
|
+
# If there is no current reifier, then a reifier will be generated.
|
9
|
+
# This reifier did not exist in the topic map before.
|
10
|
+
#
|
11
|
+
# :call-seq:
|
12
|
+
# reifier! -> Topic
|
13
|
+
#
|
14
|
+
def reifier!
|
15
|
+
self.reifier ||= self.topic_map.create_topic
|
16
|
+
end
|
17
|
+
alias :create_reifier :reifier!
|
18
|
+
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
@@ -1,14 +1,16 @@
|
|
1
1
|
# Copyright: Copyright 2009 Topic Maps Lab, University of Leipzig.
|
2
2
|
# License: Apache License, Version 2.0
|
3
3
|
|
4
|
-
module Sugar::Role
|
4
|
+
module RTM::Sugar::Role
|
5
5
|
module Counterparts
|
6
6
|
|
7
|
-
# Returns all
|
7
|
+
# Returns all roles from the parent association of this role,
|
8
8
|
# except itself.
|
9
9
|
#
|
10
|
-
# A filter-hash may be used to filter for the type of the other
|
11
|
-
# (:otype)
|
10
|
+
# A filter-hash may be used to filter for the type of the other roles
|
11
|
+
# (:otype) or the player of the other roles (:oplayer).
|
12
|
+
#
|
13
|
+
# The identfiers may be topic references.
|
12
14
|
#
|
13
15
|
# :call-seq:
|
14
16
|
# counterparts -> Array of Roles
|
@@ -16,7 +18,11 @@ module Sugar::Role
|
|
16
18
|
#
|
17
19
|
def counterparts(filter={})
|
18
20
|
_roles = parent.roles.reject{|r| r.id==self.id}
|
19
|
-
|
21
|
+
otype = filter[:otype]
|
22
|
+
_roles = _roles.select{|r| r.type == topic_map.get(otype)} if otype && otype != :any
|
23
|
+
oplayer = filter[:oplayer]
|
24
|
+
_roles = _roles.select{|r| r.player == topic_map.get(oplayer)} if oplayer && oplayer != :any
|
25
|
+
return _roles
|
20
26
|
end
|
21
27
|
|
22
28
|
# Returns the other role, if the parent association is binary.
|
@@ -35,7 +41,7 @@ module Sugar::Role
|
|
35
41
|
# except the player of itself.
|
36
42
|
#
|
37
43
|
# A filter-hash may be used to filter for the type of the other Roles
|
38
|
-
# (:otype). The identifier may be a
|
44
|
+
# (:otype). The identifier may be a topic reference.
|
39
45
|
#
|
40
46
|
# :call-seq:
|
41
47
|
# counterplayers -> Array of Topics
|
@@ -0,0 +1,74 @@
|
|
1
|
+
# Copyright: Copyright 2009 Topic Maps Lab, University of Leipzig.
|
2
|
+
# License: Apache License, Version 2.0
|
3
|
+
|
4
|
+
module RTM::Sugar::Topic::BestName
|
5
|
+
|
6
|
+
# Tries to find the best matching name for a given topic.
|
7
|
+
#
|
8
|
+
def best_name (theme = nil)
|
9
|
+
all_names = self.names
|
10
|
+
|
11
|
+
# return last part of identifier if no name exist
|
12
|
+
return find_user_friendly_identifier(self) if all_names.empty
|
13
|
+
|
14
|
+
# collect name with default name type
|
15
|
+
default_names = []
|
16
|
+
all_names.each do |name|
|
17
|
+
type_of_name = name.getType
|
18
|
+
|
19
|
+
next if type_of_name.nil?
|
20
|
+
type_identifiers = type_of_name.subject_identifiers.to_a
|
21
|
+
|
22
|
+
type_identifiers.each do |i|
|
23
|
+
if i.toExternalForm == RTM::PSI[:name_type] then
|
24
|
+
default_names << name
|
25
|
+
break
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
default_names = all_names if default_names.empty?
|
31
|
+
default_names = default_names.select { |name| not name.scope.to_a.index(theme).nil? } if not theme.nil?
|
32
|
+
default_names = all_names if default_names.empty?
|
33
|
+
|
34
|
+
# get default name with the minimum number of scopes
|
35
|
+
min_scoped_name = default_names.sort_by{|n| n.value}.min {|n1,n2| n1.getScope.size <=> n2.getScope.size}
|
36
|
+
min_scoped_name.value
|
37
|
+
end
|
38
|
+
|
39
|
+
private
|
40
|
+
def find_user_friendly_identifier(topic)
|
41
|
+
return psi_prefix topic.
|
42
|
+
subject_identifiers.
|
43
|
+
sort_by{|sid| sid.value.length}.
|
44
|
+
first.
|
45
|
+
value unless topic.subject_identifiers.empty?
|
46
|
+
|
47
|
+
return topic.
|
48
|
+
topic_references.
|
49
|
+
map{|sid| sid.gsub /^[\^=]/, ''}.
|
50
|
+
sort_by{|sid| sid.length }.
|
51
|
+
first
|
52
|
+
|
53
|
+
# fallback
|
54
|
+
return create_shortest_topic_identifier topic
|
55
|
+
end
|
56
|
+
|
57
|
+
def create_shortest_topic_identifier(topic)
|
58
|
+
base_iri = topic.topic_map.base_locator
|
59
|
+
|
60
|
+
topic.getItemIdentifiers.each do |item_identifier|
|
61
|
+
iid_iri = item_identifier.value
|
62
|
+
iid_iri.scan(/(file:)?\/*#{base_iri}#(.*)/) { |pair| return "^#{pair[1]}" }
|
63
|
+
end
|
64
|
+
|
65
|
+
CGI::escape(topic.topic_references.sort_by { |reference| reference.length }.first.to_s)
|
66
|
+
|
67
|
+
# throw('Unable to create simplified identifier from topic.', topic)
|
68
|
+
end
|
69
|
+
|
70
|
+
# HACK
|
71
|
+
def psi_prefix(name)
|
72
|
+
name.gsub /^http\:\/\/psi\.topicmaps\.org\/iso13250\/model\//, 'tmdm:'
|
73
|
+
end
|
74
|
+
end
|
@@ -1,9 +1,9 @@
|
|
1
1
|
# Copyright: Copyright 2009 Topic Maps Lab, University of Leipzig.
|
2
2
|
# License: Apache License, Version 2.0
|
3
3
|
|
4
|
-
module Sugar::Topic::Characteristics
|
4
|
+
module RTM::Sugar::Topic::Characteristics
|
5
5
|
|
6
|
-
# Returns all Occurrences of this Topic whose
|
6
|
+
# Returns all Occurrences of this Topic whose datatype is not IRI
|
7
7
|
#
|
8
8
|
# :call-seq:
|
9
9
|
# internal_occurrences -> Set of Occurrences
|
@@ -12,7 +12,7 @@ module Sugar::Topic::Characteristics
|
|
12
12
|
occurrences.select{|x| x.getDatatype.toExternalForm != RTM::PSI[:IRI]}
|
13
13
|
end
|
14
14
|
|
15
|
-
# Returns all Occurrences of this Topic whose
|
15
|
+
# Returns all Occurrences of this Topic whose datatype is IRI
|
16
16
|
#
|
17
17
|
# :call-seq:
|
18
18
|
# external_occurrences -> Set of Occurrences
|
@@ -21,15 +21,15 @@ module Sugar::Topic::Characteristics
|
|
21
21
|
occurrences.select{|y| y.getDatatype.toExternalForm == RTM::PSI[:IRI]}
|
22
22
|
end
|
23
23
|
|
24
|
-
# Returns the
|
24
|
+
# Returns the names of this topic which may be filtered for their type,
|
25
25
|
# value and/or scope.
|
26
26
|
#
|
27
|
-
# If scope is set to :ucs,
|
27
|
+
# If scope is set to :ucs, names which exist in the unconstrained scope
|
28
28
|
# are selected. If scope is set to :any (default), scope does not constrain
|
29
|
-
# the
|
30
|
-
# are
|
29
|
+
# the names-Array. Else, only the names which whose scope contains one of the
|
30
|
+
# given themes are returned.
|
31
31
|
#
|
32
|
-
# Returns an empty Array if no
|
32
|
+
# Returns an empty Array if no names match or if the name type
|
33
33
|
# or scope does not exist.
|
34
34
|
#
|
35
35
|
# :call-seq:
|
@@ -57,8 +57,8 @@ module Sugar::Topic::Characteristics
|
|
57
57
|
#
|
58
58
|
# If scope is set to :ucs, Occurrences which exist in the unconstrained scope
|
59
59
|
# are selected. If scope is set to :any (default), scope does not constrain
|
60
|
-
# the Occurrence-Array. Else, only the
|
61
|
-
# are
|
60
|
+
# the Occurrence-Array. Else, only the occurrences which whose scope contains
|
61
|
+
# one of the given themes are returned.
|
62
62
|
#
|
63
63
|
# Returns an empty Array if no Occurrences match or if the Occurrence type or
|
64
64
|
# scope does not exist.
|
@@ -1,138 +1,150 @@
|
|
1
1
|
# Copyright: Copyright 2009 Topic Maps Lab, University of Leipzig.
|
2
2
|
# License: Apache License, Version 2.0
|
3
3
|
|
4
|
-
module Sugar
|
5
|
-
module
|
6
|
-
module Counterparts
|
4
|
+
module RTM::Sugar::Topic
|
5
|
+
module Counterparts
|
7
6
|
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
7
|
+
# Returns all Roles belonging to Associations in which this Topic
|
8
|
+
# is a player and for which this Topic is not the player.
|
9
|
+
#
|
10
|
+
# A filter-hash may be used to filter for the the type
|
11
|
+
# of the Role this Topic playes
|
12
|
+
# (:rtype), for the Association type (:atype) and/or
|
13
|
+
# for the type of the returned Roles (:otype). The
|
14
|
+
# identifier may be a topic reference.
|
15
|
+
#
|
16
|
+
# The result may be empty.
|
17
|
+
#
|
18
|
+
# :call-seq:
|
19
|
+
# counterparts -> Array of Roles
|
20
|
+
# counterparts({:rtype => identifier}) -> Array of Roles
|
21
|
+
# counterparts({:atype => identifier}) -> Array of Roles
|
22
|
+
# counterparts({:otype => identifier}) -> Array of Roles
|
23
|
+
# counterparts({:rtype => identifier, :atype => identifier}) -> Array of Roles
|
24
|
+
# counterparts({:rtype => identifier, :atype => identifier, :otype => identifier}) -> Array of Roles
|
25
|
+
#
|
26
|
+
def counterparts(filter={})
|
27
|
+
roles.select{|r| filter[:rtype] ? r.type == self.topic_map.get(filter[:rtype]) : true}.
|
28
|
+
select{|r| filter[:atype] ? r.parent.type == self.topic_map.get(filter[:atype]) : true}.
|
29
|
+
inject([]){|all,r| all+=r.counterparts(filter)}
|
30
|
+
end
|
32
31
|
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
32
|
+
# Returns all Topics that are players of Roles belonging to Associations
|
33
|
+
# in which this Topic is another player. The resulting Array does
|
34
|
+
# not contain duplicates.
|
35
|
+
#
|
36
|
+
# A filter-hash may be used to filter for the the type
|
37
|
+
# of the Role this Topic playes
|
38
|
+
# (:rtype), for the Association type (:atype) and/or
|
39
|
+
# for the type of the Roles the returned Topics play (:otype). The
|
40
|
+
# identifier may be a topic reference.
|
41
|
+
#
|
42
|
+
# The result may be empty.
|
43
|
+
#
|
44
|
+
# :call-seq:
|
45
|
+
# counterplayers -> Array of Topics
|
46
|
+
# counterplayers(:rtype => identifier) -> Array of Topics
|
47
|
+
# counterplayers(:atype => identifier) -> Array of Topics
|
48
|
+
# counterplayers(:otype => identifier) -> Array of Topics
|
49
|
+
# counterplayers(:rtype => identifier1, :atype => identifier2) -> Array of Topics
|
50
|
+
# counterplayers(:rtype => identifier1, :atype => identifier2, :otype => identifier3) -> Array of Topics
|
51
|
+
#
|
52
|
+
def counterplayers(filter={})
|
53
|
+
topic_map.cached self, :counterplayers, filter do
|
54
|
+
counterparts(filter).map{|r| r.player}.uniq
|
55
55
|
end
|
56
|
+
end
|
56
57
|
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
end
|
84
|
-
elsif self.roles.map{|r| r.parent.type}.include?(type) #->atype
|
85
|
-
self.roles.select{|r| r.parent.type == type}.each do |r|
|
86
|
-
_peers = _peers + r.peers(:arity => :loose, :atype => :strict, :otype => :loose, :rtype => :strict)
|
87
|
-
end
|
88
|
-
elsif self.roles.map{|r| r.counterparts}.flatten.map{|r| r.type}.include?(type) #-> otype
|
89
|
-
# nothing can happen so far
|
90
|
-
else
|
91
|
-
return []
|
58
|
+
# Returns all players (Topics) which share a counterplayer with this Topic (player),
|
59
|
+
# If type is given, it may constrain the type of the Role this Topic should play
|
60
|
+
# (and therefore the type of the Roles the peers play)
|
61
|
+
# or the type of the Association this Topic plays a Role in
|
62
|
+
# (and therefore the type of the Associations the peers play an Role in).
|
63
|
+
#
|
64
|
+
# Type may be a topic reference.
|
65
|
+
#
|
66
|
+
# The result may be empty.
|
67
|
+
#
|
68
|
+
# :call-seq:
|
69
|
+
# peers -> Array of Topics
|
70
|
+
# peers(type) -> Array of Topics
|
71
|
+
#
|
72
|
+
def peers(type=:any)
|
73
|
+
_peers = []
|
74
|
+
if type == :any
|
75
|
+
self.roles.each do |r|
|
76
|
+
_peers = _peers + r.peers(:arity => :loose, :atype => :loose, :otype => :loose, :rtype => :loose)
|
77
|
+
end
|
78
|
+
else
|
79
|
+
type = topic_map.get(type)
|
80
|
+
if type
|
81
|
+
if self.roles.map{|r| r.type}.include?(type) #-> rtype
|
82
|
+
self.roles(type).each do |r|
|
83
|
+
_peers = _peers + r.peers(:arity => :loose, :atype => :loose, :otype => :loose, :rtype => :strict)
|
92
84
|
end
|
85
|
+
elsif self.roles.map{|r| r.parent.type}.include?(type) #->atype
|
86
|
+
self.roles.select{|r| r.parent.type == type}.each do |r|
|
87
|
+
_peers = _peers + r.peers(:arity => :loose, :atype => :strict, :otype => :loose, :rtype => :strict)
|
88
|
+
end
|
89
|
+
elsif self.roles.map{|r| r.counterparts}.flatten.map{|r| r.type}.include?(type) #-> otype
|
90
|
+
# nothing can happen so far
|
93
91
|
else
|
94
92
|
return []
|
95
93
|
end
|
94
|
+
else
|
95
|
+
return []
|
96
96
|
end
|
97
|
-
return _peers.map{|r| r.player}
|
98
97
|
end
|
98
|
+
return _peers.map{|r| r.player}
|
99
|
+
end
|
99
100
|
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
101
|
+
# Returns all Associations in which this Topic
|
102
|
+
# is a player.
|
103
|
+
#
|
104
|
+
# A filter-hash may be used to filter
|
105
|
+
# for the type of the Role this Topic plays (:rtype),
|
106
|
+
# for the Association type (:atype),
|
107
|
+
# for the type of another role (:otype) as well as
|
108
|
+
# for the player of this other role (:oplayer).
|
109
|
+
# Each value of this filter-hash may be a topic reference.
|
110
|
+
#
|
111
|
+
# The result may be empty.
|
112
|
+
#
|
113
|
+
# :call-seq:
|
114
|
+
# associations_played -> Array of Associations
|
115
|
+
# associations_played({:rtype => identifier}) -> Array of Associations
|
116
|
+
# associations_played({:atype => identifier}) -> Array of Associations
|
117
|
+
# associations_played({:otype => identifier}) -> Array of Associations
|
118
|
+
# associations_played({:otype => identifier, :oplayer => identifier}) -> Array of Associations
|
119
|
+
# associations_played({:rtype => identifier, :atype => identifier}) -> Array of Associations
|
120
|
+
# associations_played({:rtype => identifier, :atype => identifier, :otype => identifier}) -> Array of Associations
|
121
|
+
# associations_played({:rtype => identifier, :atype => identifier, :otype => identifier, :oplayer => identifier}) -> Array of Associations
|
122
|
+
#
|
123
|
+
def associations_played(filter = {})
|
124
|
+
topic_map.cached self, :associations_played, filter do
|
125
|
+
raise("associations_played(filter): filter must be a Hash") unless filter.is_a?(Hash)
|
126
|
+
default_hash = {:rtype => :any, :atype => :any, :otype => :any, :oplayer => :any}
|
127
|
+
filter = default_hash.merge(filter)
|
128
|
+
|
129
|
+
# get all roles played
|
130
|
+
roles = self.roles_played(filter[:rtype], filter[:atype])
|
131
|
+
filter.delete(:rtype)
|
132
|
+
filter.delete(:atype)
|
133
|
+
|
134
|
+
#filter for the other roles types and players if there are other roles
|
135
|
+
roles = roles.reject do |role|
|
136
|
+
if role.parent.roles.size == 1 #association size
|
137
|
+
if (filter[:otype] != :any) || filter[:player] != :any
|
138
|
+
end
|
139
|
+
else
|
140
|
+
role.counterparts(filter).empty?
|
141
|
+
end
|
130
142
|
end
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
end.uniq
|
143
|
+
|
144
|
+
# return parent associations
|
145
|
+
roles.map{|role| role.parent}.uniq
|
135
146
|
end
|
136
147
|
end
|
148
|
+
|
137
149
|
end
|
138
150
|
end
|