rtm 0.1.6 → 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 (146) hide show
  1. data/DISCLAIMER +10 -33
  2. data/LICENSE +201 -0
  3. data/README +3 -3
  4. data/lib/rtm.rb +148 -74
  5. data/lib/rtm/axes.rb +295 -0
  6. data/lib/rtm/axes/association.rb +76 -0
  7. data/lib/rtm/axes/associations.rb +96 -0
  8. data/lib/rtm/axes/assocs_names_occs.rb +56 -0
  9. data/lib/rtm/axes/characteristic.rb +68 -0
  10. data/lib/rtm/axes/characteristics.rb +93 -0
  11. data/lib/rtm/axes/string.rb +76 -0
  12. data/lib/rtm/axes/strings.rb +87 -0
  13. data/lib/rtm/axes/topic.rb +233 -0
  14. data/lib/rtm/axes/topics.rb +280 -0
  15. data/lib/rtm/{backward_compatibility.rb → deprecated/index_property_set.rb} +3 -0
  16. data/lib/rtm/engine.rb +58 -0
  17. data/lib/rtm/extensions.rb +11 -1
  18. data/lib/rtm/{locator_helpers.rb → helpers/locator.rb} +15 -4
  19. data/lib/rtm/{helpers.rb → helpers/no_output.rb} +3 -0
  20. data/lib/rtm/helpers/uri.rb +13 -0
  21. data/lib/rtm/io.rb +18 -0
  22. data/lib/rtm/io/from_xtm2_libxml.rb +2 -1
  23. data/lib/rtm/io/ontopia_io.rb +25 -0
  24. data/lib/rtm/io/tmapix.rb +234 -0
  25. data/lib/rtm/io/to_hash.rb +116 -0
  26. data/lib/rtm/io/to_jtm.rb +53 -103
  27. data/lib/rtm/io/to_rdf.rb +30 -0
  28. data/lib/rtm/io/to_string.rb +8 -6
  29. data/lib/rtm/io/to_xtm1.rb +6 -4
  30. data/lib/rtm/io/to_xtm2.rb +10 -8
  31. data/lib/rtm/io/to_yaml.rb +29 -98
  32. data/lib/rtm/navigation.rb +37 -0
  33. data/lib/rtm/navigation/association/players.rb +25 -0
  34. data/lib/rtm/navigation/name/atomify.rb +19 -0
  35. data/lib/rtm/navigation/name/characteristics.rb +33 -0
  36. data/lib/rtm/navigation/occurrence/atomify.rb +19 -0
  37. data/lib/rtm/navigation/occurrence/characteristics.rb +33 -0
  38. data/lib/rtm/navigation/topic/characteristics.rb +33 -0
  39. data/lib/rtm/navigation/topic/indicators.rb +31 -0
  40. data/lib/rtm/navigation/topic/items.rb +31 -0
  41. data/lib/rtm/navigation/topic/locators.rb +31 -0
  42. data/lib/rtm/navigation/topic/players.rb +27 -0
  43. data/lib/rtm/navigation/topic/supertypes.rb +162 -0
  44. data/lib/rtm/navigation/topic/traverse.rb +51 -0
  45. data/lib/rtm/navigation/topic/types.rb +107 -0
  46. data/lib/rtm/psi.rb +33 -2
  47. data/lib/rtm/sugar.rb +34 -0
  48. data/lib/rtm/sugar/association/hash_access.rb +46 -0
  49. data/lib/rtm/sugar/occurrence/dynamic_value.rb +75 -0
  50. data/lib/rtm/{pimp_my_api.rb → sugar/occurrence/externalize.rb} +3 -0
  51. data/lib/rtm/sugar/role/counterparts.rb +133 -46
  52. data/lib/rtm/sugar/topic/characteristics.rb +126 -12
  53. data/lib/rtm/sugar/topic/counterparts.rb +130 -7
  54. data/lib/rtm/sugar/topic/hash_access.rb +140 -30
  55. data/lib/rtm/sugar/topic/scoped.rb +65 -0
  56. data/lib/rtm/sugar/topic/topic_ref.rb +35 -0
  57. data/lib/rtm/sugar/topic/typed.rb +159 -0
  58. data/lib/rtm/sugar/typed/types.rb +38 -0
  59. data/lib/rtm/validation.rb +8 -5
  60. data/lib/rtm/version.rb +18 -0
  61. data/spec/helpers/spec_exampleexamplegroup.rb +14 -0
  62. data/spec/rtm/axes/association_spec.rb +88 -0
  63. data/spec/rtm/axes/associations_spec.rb +60 -0
  64. data/spec/rtm/axes/assocs_names_occs_spec.rb +9 -0
  65. data/spec/rtm/axes/characteristic_spec.rb +90 -0
  66. data/spec/rtm/axes/characteristics_spec.rb +85 -0
  67. data/spec/rtm/axes/string_spec.rb +145 -0
  68. data/spec/rtm/axes/strings_spec.rb +168 -0
  69. data/spec/rtm/axes/topic_spec.rb +124 -0
  70. data/spec/rtm/axes/topics_spec.rb +103 -0
  71. data/spec/rtm/base_spec.rb +32 -0
  72. data/spec/rtm/io/tmapix_spec.rb +85 -0
  73. data/spec/rtm/navigation/association/players_spec.rb +58 -0
  74. data/spec/rtm/navigation/association_spec.rb +52 -0
  75. data/spec/rtm/navigation/name/atomify_spec.rb +27 -0
  76. data/spec/rtm/navigation/name/characteristics_spec.rb +34 -0
  77. data/spec/rtm/navigation/name_spec.rb +52 -0
  78. data/spec/rtm/navigation/occurrence/atomify_spec.rb +27 -0
  79. data/spec/rtm/navigation/occurrence/characteristics_spec.rb +34 -0
  80. data/spec/rtm/navigation/occurrence_spec.rb +52 -0
  81. data/spec/rtm/navigation/string_spec.rb +51 -0
  82. data/spec/rtm/navigation/topic/characteristics_spec.rb +55 -0
  83. data/spec/rtm/navigation/topic/indicators_spec.rb +43 -0
  84. data/spec/rtm/navigation/topic/items_spec.rb +44 -0
  85. data/spec/rtm/navigation/topic/locators_spec.rb +44 -0
  86. data/spec/rtm/navigation/topic/players_spec.rb +48 -0
  87. data/spec/rtm/navigation/topic/scope_spec.rb +41 -0
  88. data/spec/rtm/navigation/topic/supertypes_spec.rb +376 -0
  89. data/spec/rtm/navigation/topic/traverse_spec.rb +64 -0
  90. data/spec/rtm/navigation/topic/types_spec.rb +195 -0
  91. data/spec/rtm/navigation/topic_spec.rb +153 -0
  92. data/spec/rtm/sugar/association/hash_access_spec.rb +55 -0
  93. data/spec/rtm/sugar/occurrence/dynamic_value_spec.rb +16 -0
  94. data/spec/rtm/sugar/role/counterparts_spec.rb +191 -0
  95. data/spec/rtm/sugar/topic/characteristics_spec.rb +318 -0
  96. data/spec/rtm/sugar/topic/counterparts_spec.rb +184 -0
  97. data/spec/rtm/sugar/topic/hash_access_spec.rb +234 -0
  98. data/spec/rtm/sugar/topic/scoped_spec.rb +131 -0
  99. data/spec/rtm/sugar/topic/topic_ref_spec.rb +44 -0
  100. data/spec/rtm/sugar/topic/typed_spec.rb +155 -0
  101. data/spec/rtm/sugar/typed/types_spec.rb +24 -0
  102. data/spec/rtm/tmapi/core/association_spec.rb +169 -0
  103. data/spec/rtm/tmapi/core/construct_spec.rb +25 -0
  104. data/spec/rtm/tmapi/core/name_spec.rb +85 -0
  105. data/spec/rtm/tmapi/core/occurrence_spec.rb +96 -0
  106. data/spec/rtm/tmapi/core/reifiable_spec.rb +168 -0
  107. data/spec/rtm/tmapi/core/role_spec.rb +73 -0
  108. data/spec/rtm/tmapi/core/scoped_spec.rb +403 -0
  109. data/spec/rtm/tmapi/core/topic_map_spec.rb +648 -0
  110. data/spec/rtm/tmapi/core/topic_spec.rb +992 -0
  111. data/spec/rtm/tmapi/core/typed_spec.rb +112 -0
  112. data/spec/rtm/tmapi/core/variant_spec.rb +52 -0
  113. data/spec/rtm/tmapi/ext/java_util_set_spec.rb +34 -0
  114. data/spec/rtm/tmapi_spec.rb +44 -0
  115. data/spec/rtm/utils/sparql_spec.rb +26 -0
  116. data/spec/rtm_spec.rb +94 -0
  117. data/spec/spec_helper.rb +23 -0
  118. data/test/base_unit_test.rb +161 -0
  119. data/test/{base_test.rb → base_unit_test_tmapi.rb} +46 -43
  120. metadata +122 -66
  121. data/COPYRIGHT +0 -4
  122. data/lib/Rakefile.rb +0 -42
  123. data/lib/activetopicmaps.rb +0 -278
  124. data/lib/rtm/backend/active_record.rb +0 -58
  125. data/lib/rtm/backend/active_record/001_initial_schema.rb +0 -116
  126. data/lib/rtm/backend/active_record/association_and_role.rb +0 -33
  127. data/lib/rtm/backend/active_record/locators.rb +0 -55
  128. data/lib/rtm/backend/active_record/name_variant_occurrence.rb +0 -45
  129. data/lib/rtm/backend/active_record/quaaxtm2rtm.rb +0 -113
  130. data/lib/rtm/backend/active_record/quaaxtm2rtmviews.rb +0 -134
  131. data/lib/rtm/backend/active_record/set_wrapper.rb +0 -98
  132. data/lib/rtm/backend/active_record/tm_construct.rb +0 -62
  133. data/lib/rtm/backend/active_record/tm_delegator.rb +0 -345
  134. data/lib/rtm/backend/active_record/tm_set_delegator.rb +0 -195
  135. data/lib/rtm/backend/active_record/tmdm.rb +0 -298
  136. data/lib/rtm/backend/active_record/topic.rb +0 -87
  137. data/lib/rtm/backend/active_record/topic_map.rb +0 -314
  138. data/lib/rtm/backend/active_record/traverse_associations.rb +0 -87
  139. data/lib/rtm/base.rb +0 -92
  140. data/lib/rtm/connect.rb +0 -92
  141. data/lib/rtm/core_ext.rb +0 -6
  142. data/lib/rtm/io/from_xtm2.rb +0 -263
  143. data/lib/rtm/merging/merging.rb +0 -307
  144. data/lib/rtm/sugar/topic/identifier_direct.rb +0 -11
  145. data/lib/rtm/sugar/topic/predefined_associations.rb +0 -42
  146. data/lib/run_main_project.rb +0 -16
data/lib/rtm/psi.rb CHANGED
@@ -1,3 +1,6 @@
1
+ # Copyright: Copyright 2009 Topic Maps Lab, University of Leipzig.
2
+ # License: Apache License, Version 2.0
3
+
1
4
  module RTM
2
5
  PSI = {}
3
6
  PSI[:type_instance] = "http://psi.topicmaps.org/iso13250/model/type-instance"
@@ -20,10 +23,18 @@ module RTM
20
23
  #PSI[:XTMxx] = "http://www.topicmaps.org/xtm/"
21
24
  #PSI[:XS] = "http://www.w3.org/2001/XMLSchema"
22
25
  #PSI[:DC] = "http://purl.org/dc/elements/1.1/"
26
+ PSI[:Float] = "http://www.w3.org/2001/XMLSchema#float"
27
+ PSI[:Double] = "http://www.w3.org/2001/XMLSchema#double"
28
+ PSI[:Long] = "http://www.w3.org/2001/XMLSchema#long"
29
+ PSI[:Integer] = "http://www.w3.org/2001/XMLSchema#integer"
30
+ PSI[:Int] = "http://www.w3.org/2001/XMLSchema#int"
31
+ PSI[:Decimal] = "http://www.w3.org/2001/XMLSchema#decimal"
23
32
 
24
33
  PSI[:XTM] = "http://psi.topicmaps.org/iso13250/glossary/XTM"
25
34
  PSI[:association] = "http://psi.topicmaps.org/iso13250/glossary/association"
35
+ PSI[:role] = "http://psi.topicmaps.org/iso13250/glossary/association-role"
26
36
  PSI[:association_role] = "http://psi.topicmaps.org/iso13250/glossary/association-role"
37
+ PSI[:role_type] = "http://psi.topicmaps.org/iso13250/glossary/association-role-type"
27
38
  PSI[:association_role_type] = "http://psi.topicmaps.org/iso13250/glossary/association-role-type"
28
39
  PSI[:association_type] = "http://psi.topicmaps.org/iso13250/glossary/association-type"
29
40
  PSI[:information_resource] = "http://psi.topicmaps.org/iso13250/glossary/information-resource"
@@ -41,14 +52,33 @@ module RTM
41
52
  PSI[:subject_locator] = "http://psi.topicmaps.org/iso13250/glossary/subject-locator"
42
53
  PSI[:topic] = "http://psi.topicmaps.org/iso13250/glossary/topic"
43
54
  PSI[:topic_map] = "http://psi.topicmaps.org/iso13250/glossary/topic-map"
55
+ PSI[:construct] = "http://psi.topicmaps.org/iso13250/glossary/topic-map-construct"
44
56
  PSI[:topic_map_construct] = "http://psi.topicmaps.org/iso13250/glossary/topic-map-construct"
45
57
  PSI[:Topic_Maps] = "http://psi.topicmaps.org/iso13250/glossary/Topic-Maps"
46
58
  PSI[:topic_name] = "http://psi.topicmaps.org/iso13250/glossary/topic-name"
47
59
  PSI[:topic_name_type] = "http://psi.topicmaps.org/iso13250/glossary/topic-name-type"
48
60
  PSI[:topic_type] = "http://psi.topicmaps.org/iso13250/glossary/topic-type"
49
61
  PSI[:unconstrained_scope] = "http://psi.topicmaps.org/iso13250/glossary/unconstrained-scope"
62
+ PSI[:variant] = "http://psi.topicmaps.org/iso13250/glossary/variant-name"
50
63
  PSI[:variant_name] = "http://psi.topicmaps.org/iso13250/glossary/variant-name"
51
64
 
65
+ # languages
66
+ # PSI[:] = "http://psi.oasis-open.org/iso/639/#"
67
+ PSI[:language] = "http://psi.oasis-open.org/iso/639/#language"
68
+ PSI[:language_group] = "http://psi.oasis-open.org/iso/639/#language-group"
69
+ PSI[:code_a2] = "http://psi.oasis-open.org/iso/639/#code-a2"
70
+ PSI[:code_a3b] = "http://psi.oasis-open.org/iso/639/#code-a3b"
71
+ PSI[:code_a3t] = "http://psi.oasis-open.org/iso/639/#code-a3t"
72
+ PSI[:multiple_languages] = "http://psi.oasis-open.org/iso/639/#mul"
73
+ #PSI[:czech] = "http://psi.oasis-open.org/iso/639/#ces"
74
+ #PSI[:dutch] = "http://psi.oasis-open.org/iso/639/#nld"
75
+ #PSI[:english] = "http://psi.oasis-open.org/iso/639/#eng"
76
+ #PSI[:french] = "http://psi.oasis-open.org/iso/639/#fra"
77
+ #PSI[:german] = "http://psi.oasis-open.org/iso/639/#deu"
78
+ #PSI[:italien] = "http://psi.oasis-open.org/iso/639/#ita"
79
+ #PSI[:japanese] = "http://psi.oasis-open.org/iso/639/#jpn"
80
+
81
+
52
82
  PSI1 = {}
53
83
  PSI1[:XTM] = "http://www.topicmaps.org/xtm/1.0/core.xtm"
54
84
  PSI1[:topic] = "http://www.topicmaps.org/xtm/1.0/core.xtm#topic"
@@ -67,7 +97,8 @@ module RTM
67
97
  PREFIX[:tm] = "http://psi.topicmaps.org/iso13250/model/" # This is the namespace for the concepts defined by TMDM.
68
98
  PREFIX[:glossary] = "http://psi.topicmaps.org/iso13250/glossary/"
69
99
  PREFIX[:xsd] = "http://www.w3.org/2001/XMLSchema#" # This is the namespace for the XML Schema Datatypes.
70
- PREFIX[:tmql] = "http://psi.topicmaps.org/tmql/1.0/" # Under this prefix the concepts of TMQL itself are located.
71
- PREFIX[:fn] = "http://psi.topicmaps.org/tmql/1.0/functions" # Under this prefix user-callable functions of the predefined TMQL environment are located.
100
+ PREFIX[:tmql] = "http://psi.topicmaps.org/tmql/1.0/" # Under this prefix the concepts of Axes itself are located.
101
+ PREFIX[:fn] = "http://psi.topicmaps.org/tmql/1.0/functions" # Under this prefix user-callable functions of the predefined Axes environment are located.
72
102
  PREFIX[:xtm1] = "http://www.topicmaps.org/xtm/1.0/core.xtm#"
103
+ PREFIX[:language] = "http://psi.oasis-open.org/iso/639/#" # This is the namespace for the languae PSIs
73
104
  end
data/lib/rtm/sugar.rb ADDED
@@ -0,0 +1,34 @@
1
+ # Copyright: Copyright 2009 Topic Maps Lab, University of Leipzig.
2
+ # License: Apache License, Version 2.0
3
+
4
+ module RTM::Topic
5
+ require 'rtm/sugar/topic/topic_ref'
6
+ include Sugar::Topic::TopicRef
7
+ require 'rtm/sugar/topic/hash_access'
8
+ include RTM::Sugar::Topic::HashAccess
9
+ require 'rtm/sugar/topic/characteristics'
10
+ include Sugar::Topic::Characteristics
11
+ require 'rtm/sugar/topic/counterparts'
12
+ include Sugar::Topic::Counterparts
13
+ require 'rtm/sugar/topic/scoped'
14
+ include Sugar::Topic::Scoped
15
+ require 'rtm/sugar/topic/typed'
16
+ include Sugar::Topic::Typed
17
+ end
18
+ module RTM::Association
19
+ require "rtm/sugar/association/hash_access"
20
+ include Sugar::Association::HashAccess
21
+ end
22
+ module RTM::Role
23
+ require "rtm/sugar/role/counterparts"
24
+ include Sugar::Role::Counterparts
25
+ end
26
+ module RTM::Occurrence
27
+ require "rtm/sugar/occurrence/dynamic_value"
28
+ include Sugar::Occurrence::DynamicValue
29
+ end
30
+ module RTM::Typed
31
+ require "rtm/sugar/typed/types"
32
+ include Sugar::Typed::Types
33
+ end
34
+
@@ -0,0 +1,46 @@
1
+ # Copyright: Copyright 2009 Topic Maps Lab, University of Leipzig.
2
+ # License: Apache License, Version 2.0
3
+
4
+ module Sugar
5
+ module Association
6
+ # This module implements methods for Hash-like access in Associations.
7
+ module HashAccess
8
+
9
+ # Returns all Roles of this Association.
10
+ #
11
+ # If type is given, returns the Roles of this Association
12
+ # whose Role type match type.
13
+ # Type may be a Topic or Topic-Reference.
14
+ #
15
+ # The result may be empty.
16
+ #
17
+ # :call-seq:
18
+ # [] -> Array of Roles
19
+ # [type] -> Array of Roles
20
+ #
21
+ def [](type=:any)
22
+ return getRoles.to_a if type == :any
23
+ return getRoles.to_a unless type
24
+ type = topic_map.get(type)
25
+ if type
26
+ return getRoles(type).to_a
27
+ else
28
+ return []
29
+ end
30
+ end
31
+
32
+
33
+ # Creates a new Role in this Association where type specifies the
34
+ # Role type and player the associated Role player.
35
+ # Type and player may each be a Topic, String-Reference or Locator.
36
+ #
37
+ # :call-seq:
38
+ # [type]= player
39
+ #
40
+ # TODO Issue #919
41
+ def []=(type,player)
42
+ create_role(type,player)
43
+ end
44
+ end
45
+ end
46
+ end
@@ -0,0 +1,75 @@
1
+ # Copyright: Copyright 2010 Topic Maps Lab, University of Leipzig.
2
+ # License: Apache License, Version 2.0
3
+
4
+ module Sugar::Occurrence
5
+ module DynamicValue
6
+ # Returns the value of this occurrence cast as appropriate Ruby type.
7
+ def dynamic_value
8
+ case self.datatype.to_external_form # first_oc.datatype is actually of type Locator
9
+ when RTM::PSI[:Decimal]
10
+ self.value.to_f
11
+ when RTM::PSI[:Double]
12
+ self.value.to_f
13
+ when RTM::PSI[:Int]
14
+ self.value.to_i
15
+ when RTM::PSI[:Integer]
16
+ self.value.to_i
17
+ when RTM::PSI[:Float]
18
+ self.value.to_f
19
+ when RTM::PSI[:Long]
20
+ self.value.to_i
21
+ # Date, ... missing
22
+ else
23
+ self.value
24
+ end
25
+ end
26
+
27
+ class NoDatatypeHandlerAvailableException < Exception
28
+ def initialize(value)
29
+ super "Cannot map #{value} to an occurrence value+datatype. Maybe you need to add a handler for your Ruby object type."
30
+ end
31
+ end
32
+ end
33
+ end
34
+
35
+ class Float
36
+ def to_xsd_double
37
+ s = self.to_s
38
+
39
+ case s
40
+ when "Infinity"
41
+ "INF"
42
+ when "-Infinity"
43
+ "-INF"
44
+ else
45
+ s
46
+ end
47
+ end
48
+ end
49
+
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
@@ -1,3 +1,6 @@
1
+ # Copyright: Copyright 2009 Topic Maps Lab, University of Leipzig.
2
+ # License: Apache License, Version 2.0
3
+
1
4
  module RTM
2
5
  # Some useful or maybe not so useful stuff which I don't know how to put else.
3
6
  module PimpMyApi
@@ -1,51 +1,138 @@
1
- module RTM::Sugar
2
- module Role
3
- module Counterparts
4
- # This method fetches all roles from the parent association of this role, except itself (i.e. current role).
5
- # A filter-hash may be used to filter for the type of the other role (:otype =>topic_reference).
6
- # Examples:
7
- # this_role.counterparts # returns all
8
- # this_role.counterparts(:otype => some_topic) # returns only other roles which have type some_topic
9
- # this_role.counterparts(:otype => "some_reference") # as above, looking up the reference first
10
- def counterparts(filter={})
11
- self.parent.roles.reject{|r| r.id==self.id}.
12
- select{|r| filter[:otype] ? r.type == self.topic_map.get(filter[:otype]) : true}
13
- end
1
+ # Copyright: Copyright 2009 Topic Maps Lab, University of Leipzig.
2
+ # License: Apache License, Version 2.0
14
3
 
15
- # This methods fetches all players of the parent association of this role, except the player of itself.
16
- # It accepts a filter-hash like the counterparts-method.
17
- def counterplayers(*args)
18
- self.counterparts(*args).map{|r| r.player}
19
- end
4
+ module Sugar::Role
5
+ module Counterparts
6
+
7
+ # Returns all Roles from the parent Association of this Role,
8
+ # except itself.
9
+ #
10
+ # A filter-hash may be used to filter for the type of the other Roles
11
+ # (:otype). The identfier may be a Topic or Topic-Reference.
12
+ #
13
+ # :call-seq:
14
+ # counterparts -> Array of Roles
15
+ # counterparts({:otype => identifier}) -> Array of Roles
16
+ #
17
+ def counterparts(filter={})
18
+ _roles = parent.roles.reject{|r| r.id==self.id}
19
+ return filter[:otype] ? _roles.select{|r| r.type == topic_map.get(filter[:otype]) } : _roles
20
+ end
21
+
22
+ # Returns the other role, if the parent association is binary.
23
+ #
24
+ # :call-seq:
25
+ # counterpart -> Role
26
+ #
27
+ def counterpart
28
+ n = parent.roles.size
29
+ raise "Association must be unary or binary to use counterpart method. Please use counterparts for n-ary associations." if n > 2
30
+ return nil if n == 1
31
+ counterparts.first
32
+ end
33
+
34
+ # Returns all players of the parent Association of this Role,
35
+ # except the player of itself.
36
+ #
37
+ # A filter-hash may be used to filter for the type of the other Roles
38
+ # (:otype). The identifier may be a Topic or Topic-Reference.
39
+ #
40
+ # :call-seq:
41
+ # counterplayers -> Array of Topics
42
+ # counterplayers({:otype => identifier}) -> Array of Topics
43
+ #
44
+ def counterplayers(filter={})
45
+ counterparts(filter).map{|r| r.player}
46
+ end
47
+
48
+ # Returns the player of the other role, if the parent association is binary.
49
+ #
50
+ # :call-seq:
51
+ # counterplayer -> Topic
52
+ #
53
+ def counterplayer
54
+ n = parent.roles.size
55
+ raise "Association must be unary or binary to use counterplayer method. Please use counterplayers for n-ary associations (n>2)." if n > 2
56
+ return nil if n == 1
57
+ counterparts.first.player
58
+ end
59
+
60
+ # Returns the Roles of other binary Associations for which the following
61
+ # applies:
62
+ #
63
+ # - this Role and all returned Roles must share a counterplayer.
64
+ #
65
+ # - if :rtype is set to :strict, the type of the returned Roles must equal
66
+ # the type of this Role
67
+ #
68
+ # - if :atype is set to :strict, the type of the parent Associaton of this Role must be equal
69
+ # to the type of the parent Associations of the other Roles
70
+ #
71
+ # - if :otype is set to :strict, the type of the Roles the shared counterplayers play (counterparts)
72
+ # must equal
73
+ #
74
+ # - if :arity is set to :strict, the size of the parent Associations must
75
+ # equal the size of the other associations involved
76
+ #
77
+ # Example: Returns all employee-roles of a company, if self is a Role an employee plays in an
78
+ # "firm-employee"-Association.
79
+ #
80
+ # Default: peers(:arity => :strict, :atype => :strict, :otype => :strict, :rtype => :strict)
81
+ #
82
+ # The result may be empty. Esp. if the parent Association includes only this Role, an empty Array is returned.
83
+ #
84
+ # :call-seq:
85
+ # peers -> Array of Roles
86
+ # peers(:arity => :strict) -> Array of Roles
87
+ # peers(:rtype => :strict, :atype => strict, :otype => :loose) -> Array of Roles
88
+ # etc.
89
+ #
90
+ def peers(params = {})
91
+ default_hash = {:arity => :strict, :atype => :strict, :otype => :strict, :rtype => :strict}
92
+ raise("peers: argument has to be a Hash") unless params.is_a? Hash
93
+ params.reject!{|k,v| ![:strict,:loose].include?(v)}
94
+ params = default_hash.merge(params)
95
+ # puts "\narity = " + (params[:arity] == :strict ? "strict" : "loose")
96
+ # puts "atype = " + (params[:atype] == :strict ? "strict" : "loose")
97
+ # puts "otype = " + (params[:otype] == :strict ? "strict" : "loose")
98
+ # puts "rtype = " + (params[:rtype] == :strict ? "strict" : "loose")
99
+ n = self.parent.roles.size
100
+ return [] if n == 1
101
+ atype = self.parent.type # association type
102
+ rtype = self.type #role type
103
+ c_parts = self.counterparts # other roles in the association of this player
104
+ _roles = []
105
+ c_parts.each do |c_part|
106
+ otype = c_part.type # type of the other role in the association
107
+ c_player = c_part.player
108
+ if params[:otype] == :loose
109
+ other_roles = c_player.roles.to_a
110
+ else
111
+ if params[:atype] == :strict
112
+ other_roles = c_player.roles(otype,atype).to_a
113
+ else
114
+ other_roles = c_player.roles(otype).to_a
115
+ end
116
+ end
117
+ other_roles = other_roles.select{|r| r.parent.roles.size == n} if params[:arity] == :strict #same n-ary
118
+ other_roles = other_roles.map{|r| r.counterparts}.flatten # other roles in these associations
119
+ other_roles = other_roles.select{|r| r.type == rtype} if params[:rtype] == :strict
120
+ other_roles = other_roles.reject{|r| r == self} # reject self
121
+ _roles = _roles + other_roles
122
+ end
123
+ return _roles
124
+ end
20
125
 
21
- # Fetches the other role, if the parent association is binary.
22
- def counterpart
23
- n = self.parent.roles.size
24
- raise "Association must be unary or binary to use counterpart method. Please use counterparts for n-ary associations." if n > 2
25
- return nil if n == 1
26
- self.counterparts.first
27
- end
28
-
29
- # Fetches the player of the other role, if the parent association is binary.
30
- def counterplayer
31
- n = self.parent.roles.size
32
- raise "Association must be unary or binary to use counterplayer method. Please use counterplayers for n-ary associations." if n > 2
33
- return nil if n == 1
34
- self.counterparts.first.player
35
- end
36
-
37
- # Fetches all roles of the (binary) parent associations which play the same role in the same with the counterplayer
38
- # TODO: filter not only otype but also atype and rtype.
39
- def peers
40
- cp = self.counterpart
41
- cp.player.roles.select{|r| r.type == cp.type}.map{|r| r.counterpart}
42
- end
43
- # Fetches all players of roles being in the same association with another topic as self
44
- # Example: current_role is a role of player "me" and type "employee"
45
- # current_role.peerplayers # returns all employees of my company (including me)
46
- def peerplayers
47
- self.peers.map{|r| r.player}
48
- end
126
+ # Returns all players of the peers of this Role.
127
+ #
128
+ # Example: Returns all employees of a company except the
129
+ # player of itself.
130
+ #
131
+ # :call-seq:
132
+ # peerplayers -> Array of Topics
133
+ #
134
+ def peerplayers
135
+ peers.map{|r| r.player}
49
136
  end
50
137
  end
51
138
  end
@@ -1,15 +1,129 @@
1
- module RTM::Sugar
2
- module Topic
3
- module Characteristics
4
- def characteristics
5
- topic_names.to_a + occurrences.to_a
6
- end
7
- def internal_occurrences
8
- occurrences.select{|o| o.datatype != RTM::PSI[:IRI]}
9
- end
10
- def external_occurrences
11
- occurrences.select{|o| o.datatype == RTM::PSI[:IRI]}
12
- end
1
+ # Copyright: Copyright 2009 Topic Maps Lab, University of Leipzig.
2
+ # License: Apache License, Version 2.0
3
+
4
+ module Sugar::Topic::Characteristics
5
+
6
+ # Returns all Occurrences of this Topic whose Datatype is not IRI
7
+ #
8
+ # :call-seq:
9
+ # internal_occurrences -> Set of Occurrences
10
+ #
11
+ def internal_occurrences
12
+ occurrences.select{|x| x.getDatatype.toExternalForm != RTM::PSI[:IRI]}
13
+ end
14
+
15
+ # Returns all Occurrences of this Topic whose Datatype is IRI
16
+ #
17
+ # :call-seq:
18
+ # external_occurrences -> Set of Occurrences
19
+ #
20
+ def external_occurrences
21
+ occurrences.select{|y| y.getDatatype.toExternalForm == RTM::PSI[:IRI]}
22
+ end
23
+
24
+ # Returns the Names of this Topic which may be filtered for their type,
25
+ # value and/or scope.
26
+ #
27
+ # If scope is set to :ucs, Names which exist in the unconstrained scope
28
+ # are selected. If scope is set to :any (default), scope does not constrain
29
+ # the Names-Array. Else, only the Names which exist in the given scope
30
+ # are selected.
31
+ #
32
+ # Returns an empty Array if no Names match or if the Name type
33
+ # or scope does not exist.
34
+ #
35
+ # :call-seq:
36
+ # names_by -> Array of Names
37
+ # names_by(:type => identifier) -> Array of Names
38
+ # names_by(:value => string) -> Array of Names
39
+ # names_by(:scope => identifier) -> Array of Names
40
+ # names_by(:type => identifier, :value => string) -> Array of Names
41
+ # names_by(:type => identifier, :value => string, :scope => identifier) -> Array of Names
42
+ # and so on
43
+ #
44
+ def names_by(args = {})
45
+ raise("names_by: arguments must be a Hash") unless args.is_a?(Hash)
46
+ default_hash = {:type => :any, :value => :any, :scope => :any}
47
+ args = default_hash.merge(args)
48
+ #filter for type
49
+ _names = args[:type] == :any ? names : names(args[:type])
50
+ _names = self.filter_by(_names,args)
51
+ # return Array
52
+ return _names.to_a
53
+ end
54
+
55
+ # Returns Occurrences of this Topic which may be filtered for their type,
56
+ # value, datatype and/or scope.
57
+ #
58
+ # If scope is set to :ucs, Occurrences which exist in the unconstrained scope
59
+ # are selected. If scope is set to :any (default), scope does not constrain
60
+ # the Occurrence-Array. Else, only the Occurrences which exist in the given scope
61
+ # are selected.
62
+ #
63
+ # Returns an empty Array if no Occurrences match or if the Occurrence type or
64
+ # scope does not exist.
65
+ #
66
+ # :call-seq:
67
+ # occurrence_by -> Array of Occurrences
68
+ # occurrences_by(:type => argument) -> Array of Occurrences
69
+ # occurrences_by(:value => argument) -> Array of Occurrences
70
+ # occurrences_by(:scope => argument) -> Array of Occurrences
71
+ # occurrences_by(:datatype => argument) -> Array of Occurrences
72
+ # occurrences_by(:type => argument1, :value => argument2) -> Array of Occurrences
73
+ # occurrences_by(:type => argument1, :value => argument2, :scope => argument3, :datatype => argument4) -> Array of Occurrences
74
+ # and so on
75
+ #
76
+ def occurrences_by(args = {})
77
+ raise("occurrences_by: arguments must be a Hash") unless args.is_a?(Hash)
78
+ default_hash = {:type => :any, :value => :any, :scope => :any, :datatype => :any}
79
+ args = default_hash.merge(args)
80
+ #filter for type
81
+ _occurrences = args[:type] == :any ? occurrences : occurrences(args[:type])
82
+ _occurrences = self.filter_by(_occurrences,args)
83
+ #filter for datatype
84
+ _occurrences = _occurrences.select{|o| o.datatype == args[:datatype]} unless args[:datatype] == :any
85
+ return _occurrences.to_a
86
+ end
87
+
88
+ protected
89
+ def filter_by(_characteristics,args)
90
+ #filter for value
91
+ unless args[:value] == :any
92
+ _characteristics = args[:value].is_a?(Array) ? _characteristics.select{|o| args[:value].any?{|v| o.value == v}} : _characteristics.select{|o| o.value == args[:value]}
93
+ end
94
+ #filter for scope
95
+ case args[:scope]
96
+ when :any
97
+ when :ucs, []
98
+ _characteristics = _characteristics.select{|o| o.scope.empty?}
99
+ else
100
+ _scope = topic_map.get(args[:scope])
101
+ _characteristics = _scope.is_a?(Array) ? _characteristics.select{|o| _scope.any?{|theme| o.scope.include?(theme)}} : _characteristics.select{|o| o.scope.include?(_scope)}
13
102
  end
103
+ _characteristics
14
104
  end
105
+
106
+ # Returns the Occurrences and Names of this Topic which have the specified type as
107
+ # Occurrence/Name type. Additionally, scope may constrain the the selection.
108
+ #
109
+ # If scope is set to :ucs, Occurrences/Names which exist in the unconstrained scope
110
+ # are selected. If scope is set to :any (default), scope does not constrain
111
+ # the Occurrence/Names-Array. Else, only the Occurrences/Names which exist in the given scope
112
+ # are selected.
113
+ #
114
+ # Returns an empty Array if no Occurrences or Names match or if the Occurrence/Name type or
115
+ # scope does not exist.
116
+ #
117
+ # :call-seq:
118
+ # characteristics_by -> Array of Occurrences and Names
119
+ #
120
+ # def characteristics_by(args = {})
121
+ # raise("characteristics_by: arguments must be a Hash") unless args.is_a?(Hash)
122
+ # default_hash = {:type => :any, :value => :any, :scope => :any, :datatype => :any}
123
+ # args = default_hash.merge(args)
124
+ # _names = names_by(args) if args[:datatype].include(:any) || args[:datatype] == RTM::PSI[:String] || args[:datatype] == topic_map.create_locator(RTM::PSI[:String])
125
+ # _occurrences = occurrences_by(args)
126
+ #
127
+ # end
128
+
15
129
  end