rtm 0.1.0 → 0.1.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,229 @@
1
+ require 'rtm'
2
+ # Yep, this is the easter egg I told of on the website.
3
+ # See the source code at the very end of this file for an explanation.
4
+ # Pleace note, this is not beta code, not even alpha - it's just an experiment.
5
+
6
+ module ActiveTopicMaps
7
+ class Base
8
+ def self.inherited(klass)
9
+ klass.send(:include, ActiveTopicMaps::Topic)
10
+ end
11
+ end
12
+
13
+ module Topic
14
+ def self.included(klass)
15
+ klass.extend(ClassMethods)
16
+ end
17
+ def initialize(topic)
18
+ @topic = topic
19
+ end
20
+ def topic;@topic;end
21
+
22
+ module ClassMethods
23
+ def acts_as_topic
24
+ self.class_eval <<-EOS
25
+ def method_missing(name, *args)
26
+ @topic.send(name, *args)
27
+ end
28
+
29
+ alias atm_old_respond_to? respond_to?
30
+ def respond_to?(*args)
31
+ atm_old_respond_to?(*args) || @topic.respond_to?(*args)
32
+ end
33
+
34
+ alias old_methods methods
35
+ def methods
36
+ @methods ||= (old_methods + @topic.methods).uniq
37
+ end
38
+ EOS
39
+ end
40
+
41
+ # def acts_smart
42
+ # self.class_eval <<-EOS
43
+ # alias atm_old_method_missing method_missing
44
+ # def method_missing(name, *args)
45
+ # if @topic.respond_to?(name)
46
+ # @topic.send(name, *args)
47
+ # else
48
+ # begin
49
+ # if name =~ /=$/
50
+ # smart_setter(name, *args)
51
+ # else
52
+ # smart_getter(name, *args)
53
+ # end
54
+ # rescue
55
+ # atm_old_method_missing(name, *args)
56
+ # end
57
+ # end
58
+ # end
59
+ #
60
+ # def smart_getter(name, *args)
61
+ # val = instance_variable_set(("smart_prop_" + name.to_s).to_sym, smart_prop_name)
62
+ # prefix = ""
63
+ # smart_prop_name ||= (iname = @topic["#{prefix}#{name}"].first) ? iname.value : nil
64
+ # instance_variable_set(name, smart_prop_name)
65
+ # end
66
+ #
67
+ # def smart_setter(name, *args)
68
+ #
69
+ # end
70
+ #
71
+ # alias atm_old_respond_to? respond_to?
72
+ # def respond_to?(*args)
73
+ # atm_old_respond_to?(*args) || @topic.respond_to?(*args)
74
+ # end
75
+ # EOS
76
+ # end
77
+
78
+ def name(name, type="")
79
+ prop_getter(name, type, "-")
80
+ prop_setter(name, type, "-")
81
+ end
82
+
83
+ def occurrence(name, type=nil)
84
+ type ||= name
85
+ prop_getter(name, type)
86
+ prop_setter(name, type)
87
+ end
88
+
89
+ def prop_getter(name, type, prefix="")
90
+ self.class_eval <<-EOS
91
+ def #{name}
92
+ @#{name} ||= (iname = @topic["#{prefix}#{type}"].first) ? iname.value : nil
93
+ end
94
+ EOS
95
+ end
96
+
97
+ def prop_setter(name, type, prefix="")
98
+ self.class_eval <<-EOS
99
+ def #{name}=(name)
100
+ old = @topic["#{prefix}#{type}"].first
101
+ @#{name} = if old
102
+ old.value = name
103
+ else
104
+ @topic["#{prefix}#{type}"] = name
105
+ end
106
+ end
107
+ EOS
108
+ end
109
+
110
+ def binassoc(name, rt1, at, rt2, klass)
111
+ eval(<<-EOS)
112
+ class RTM::AR::Topic
113
+ index_property_set :#{name}, :type => :Topic, :rule => {
114
+ :transitive => true,
115
+ :role_type => "#{rt1}",
116
+ :association_type => "#{at}",
117
+ :association_arity => 2,
118
+ :other_role_type => "#{rt2}",
119
+ :add => "#{name.to_s.singularize}",
120
+ }
121
+ end
122
+ EOS
123
+ self.class_eval <<-EOS
124
+ def #{name}
125
+ @topic.#{name}.map{|o| #{klass}.new(o)}
126
+ end
127
+ def add_#{name.to_s.singularize}(o)
128
+ @topic.add_#{name.to_s.singularize}(o.topic)
129
+ end
130
+ def remove_#{name.to_s.singularize}(o)
131
+ @topic.remove_#{name.to_s.singularize}(o.topic)
132
+ end
133
+ EOS
134
+ end
135
+
136
+ def topic_map(base_uri_or_tm)
137
+ @tm = base_uri_or_tm.is_a?(RTM::TopicMap) ? base_uri_or_tm : RTM.create(base_uri_or_tm)
138
+ end
139
+
140
+ def create(ref)
141
+ self.new(@tm.get!(ref))
142
+ end
143
+ alias get! create
144
+
145
+ def find(ref)
146
+ t = @tm.get(ref)
147
+ self.new(t) if t
148
+ end
149
+ alias get find
150
+ end
151
+ end
152
+ end
153
+
154
+
155
+ #require 'activetopicmaps'
156
+ #RTM.connect
157
+ #
158
+ #class Person < ActiveTopicMaps::Base
159
+ # topic_map "urn:/base"
160
+ #
161
+ # name :name
162
+ # occurrence :age
163
+ # occurrence :shoesize, "http://rtm.rubyforge.org/psi/shoesize" # this tells ActiveTM to use this as occurrence type
164
+ #
165
+ # def to_s
166
+ # a = " (#{age})" if age
167
+ # "#{name}#{a}"
168
+ # end
169
+ #end
170
+ #
171
+ #class Country
172
+ # include ActiveTopicMaps::Topic
173
+ #
174
+ # topic_map "urn:/base"
175
+ #
176
+ # acts_as_topic
177
+ #
178
+ # name :name
179
+ # occurrence :population
180
+ # occurrence :size
181
+ #
182
+ # binassoc :inhabitants, "country", "country-inhabitant", "inhabitant", :Person
183
+ #
184
+ # def to_s
185
+ # "There is a country called #{name} with #{population} inhabitants and a size of #{size} km^2.\n" +
186
+ # "These are some of the inhabitants: #{inhabitants.map{|i| i.to_s}.join(", ")}."
187
+ # end
188
+ #end
189
+ #
190
+ ## create a new object with a (new?) topic
191
+ #p = Person.create("max")
192
+ #
193
+ ## set name, age, shoesize
194
+ #p.name = "Max Mustermann"
195
+ #p.age = 30
196
+ #p.shoesize = 44 # european ;)
197
+ #
198
+ ## print out the name
199
+ #puts p.name
200
+ #
201
+ ## create a new object, using a topic (might be queried before, ... you know)
202
+ #h = Person.new(RTM[0].get!("hans"))
203
+ #
204
+ ## set name
205
+ #h.name = "Hans Maier"
206
+ ## set another name (overwrites the old one! this is different from topic["-name"] !!!)
207
+ #h.name = "Hans Meyer"
208
+ #
209
+ ## don't know what that does, maybe you?
210
+ #puts h.name
211
+ #
212
+ ## Norway is the item identifier, here
213
+ #no=Country.create("Norway")
214
+ #
215
+ #no.name="Norway"
216
+ #no.population = "4.743.000"
217
+ #no.size = "385.199"
218
+ #
219
+ ## use real person objects here
220
+ #no.add_inhabitant h
221
+ #no.add_inhabitant p
222
+ #
223
+ ## use this nice to_s method we provided above
224
+ #puts no.to_s
225
+ #
226
+ ## find hans
227
+ #puts "Trying to find Hans: #{Person.find("hans")}"
228
+ ## won't find otto
229
+ #puts "Trying to find Otto: #{Person.find("otto")}"
@@ -0,0 +1,54 @@
1
+ module RTM::AR
2
+ class Association < Reifiable
3
+ include RTM::Association
4
+ wrapper_cache
5
+
6
+ parent :topic_map
7
+ property :type, :aka => [:ty,:t], :rw => true, :type => :Topic, :wrap => true
8
+ property_set :scope, :type => :Topic, :wrap => true
9
+ property_set :roles, :aka => [:r, :association_roles], :type => :AssociationRole, :wrap => true,
10
+ :create => :role, :create_aka => [:cr, :create_association_role],
11
+ :create_args => [ {:name => :player, :type => :Topic}, {:name => :type, :type => :Topic}]
12
+
13
+ property_set :role_players, :aka => [:players, :rp, :pl], :type => :Topic, :wrap => true
14
+ property_set :role_types, :aka => [:types, :rt], :type => :Topic, :wrap => true
15
+
16
+ equality [:scope, :type, :roles]
17
+ end
18
+
19
+ class AssociationRole < Reifiable
20
+ include RTM::AssociationRole
21
+ wrapper_cache
22
+
23
+ parent :association
24
+ property :player, :aka => [:pl,:topic], :rw => true, :type => :Topic, :wrap => true
25
+ property :type, :aka => [:ty,:t], :rw => true, :type => :Topic, :wrap => true
26
+
27
+ def counterparts
28
+ self.parent.roles.reject{|r| r.id==self.id}
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
51
+
52
+ equality [:type, :player, :parent]
53
+ end
54
+ end
@@ -0,0 +1,53 @@
1
+ module RTM::AR
2
+ class Locator < TMDelegator
3
+ include RTM::Locator
4
+
5
+ delegate :+
6
+ delegate :-
7
+ #delegate :==
8
+ delegate :id
9
+
10
+ delegate :get
11
+ delegate :hash
12
+ delegate :resolve_relative
13
+ delegate :to_s, :to => :reference
14
+ delegate :to_uri
15
+ delegate :uri
16
+ delegate :reference, :rw => true, :save => true
17
+ alias :value :reference
18
+ alias :value= :reference=
19
+
20
+ equality [:reference]
21
+
22
+ def self.wrap(obj)
23
+ return nil unless obj
24
+ raise "Double wrapping" if obj.respond_to?(:__getobj__)
25
+ case obj.class.name
26
+ when "RTM::AR::TMDM::ItemIdentifier"
27
+ ItemIdentifier.wrap(obj)
28
+ when "RTM::AR::TMDM::SubjectIdentifier"
29
+ SubjectIdentifier.wrap(obj)
30
+ when "RTM::AR::TMDM::SubjectLocator"
31
+ SubjectLocator.wrap(obj)
32
+ else
33
+ raise "Can't wrap object. Class for wrapping #{obj.class} unknown (object: #{obj})"
34
+ end
35
+ end
36
+ end
37
+
38
+ class ItemIdentifier < Locator
39
+ include RTM::ItemIdentifier
40
+ wrapper_cache
41
+ property :topic_map_construct, :type => :TopicMapConstruct, :wrap => true
42
+ end
43
+ class SubjectIdentifier < Locator
44
+ include RTM::SubjectIdentifier
45
+ wrapper_cache
46
+ property :topic, :type => :Topic, :wrap => true
47
+ end
48
+ class SubjectLocator < Locator
49
+ include RTM::SubjectLocator
50
+ wrapper_cache
51
+ property :topic, :type => :Topic, :wrap => true
52
+ end
53
+ end
@@ -0,0 +1,44 @@
1
+ module RTM::AR
2
+ class TopicName < Reifiable
3
+ include RTM::TopicName
4
+ wrapper_cache
5
+
6
+ parent :topic
7
+ property :type, :aka => [:ty,:t], :rw => true, :type => :Topic, :wrap => true
8
+ property_set :scope, :type => :Topic, :wrap => true
9
+
10
+ property_set :variants, :aka => :v, :type => :Variant, :wrap => true,
11
+ :create => :variant, :create_aka => :cv,
12
+ :create_args => [ {:name => :value, :type => [:String, :Locator]}, {:name => :scope, :type => :Collection}]
13
+
14
+ property :value, :rw => true, :type => :String
15
+
16
+ equality [:value, :type, :scope, :parent]
17
+ end
18
+
19
+ class Variant < Reifiable
20
+ include RTM::Variant
21
+ wrapper_cache
22
+
23
+ parent :topic_name, :aka => :name
24
+ property :value, :rw => true, :type => :String
25
+ property :datatype, :rw => true, :type => :Locator #, :wrap => true
26
+ property_set :scope, :type => :Topic, :wrap => true
27
+
28
+ equality [:value, :datatype, :scope, :parent]
29
+ end
30
+
31
+ class Occurrence < Reifiable
32
+ include RTM::Occurrence
33
+ wrapper_cache
34
+
35
+ parent :topic
36
+ property :value, :rw => true, :type => :String
37
+ property :datatype, :rw => true, :type => :String
38
+
39
+ property_set :scope, :type => :Topic, :wrap => true
40
+ property :type, :aka => [:ty,:t], :rw => true, :type => :Topic, :wrap => true
41
+
42
+ equality [:value, :datatype, :scope, :type, :parent]
43
+ end
44
+ end
@@ -0,0 +1,113 @@
1
+ require 'active_record'
2
+
3
+
4
+ module RTM
5
+ module AR
6
+ module TMDM
7
+ class Topic < ActiveRecord::Base;end
8
+ class ItemIdentifier < ActiveRecord::Base
9
+ belongs_to :topic_map_construct
10
+ end
11
+ class SubjectIdentifier < ActiveRecord::Base
12
+ belongs_to :topic
13
+ end
14
+
15
+ class SubjectLocator < ActiveRecord::Base
16
+ belongs_to :topic
17
+ end
18
+
19
+ class QuaaxTM2RTM < ActiveRecord::Migration
20
+ def self.up
21
+ rename_table("qtm_topicmap", "topic_maps" )
22
+ rename_column("topic_maps", "baselocator", "base_locator")
23
+
24
+ rename_table("qtm_topic", "topics")
25
+ rename_column("topics", "topicmap_id", "topic_map_id")
26
+
27
+ add_column :topics, :reified_id, :integer
28
+ add_column :topics, :reified_type, :string
29
+
30
+ rename_table "qtm_association", "associations"
31
+ rename_column "associations", "type_id", "ttype_id"
32
+ rename_column "associations", "topicmap_id", "topic_map_id"
33
+
34
+ rename_table "qtm_assocrole", "association_roles"
35
+ rename_column "association_roles", "type_id", "ttype_id"
36
+ rename_column "association_roles", "reference", "topic_id"
37
+
38
+ rename_table "qtm_topicname", "topic_names"
39
+ rename_column "topic_names", "type_id", "ttype_id"
40
+
41
+ rename_table "qtm_occurrence", "occurrences"
42
+ rename_column "occurrences", "type_id", "ttype_id"
43
+
44
+ rename_table "qtm_variant", "variants"
45
+ rename_column "variants", "topicname_id", "topic_name_id"
46
+
47
+ rename_table "qtm_topicmapconstructref", "item_identifiers"
48
+ rename_column "item_identifiers", "locator", "reference"
49
+ add_column :item_identifiers, :topic_map_id, :integer
50
+ ItemIdentifier.reset_column_information
51
+ ItemIdentifier.find(:all).each do |si|
52
+ si.update_attribute :topic_map_id, si.topic_map_construct.topic_map_id
53
+ end
54
+
55
+ create_table :item_identifiers do |t|
56
+ t.column :topic_map_id, :integer, :null => false
57
+ t.column :reference, :string, :null => false
58
+ t.column :topic_map_construct_id, :integer
59
+ t.column :topic_map_construct_type, :string
60
+ end
61
+ SubjectIdentifier.reset_column_information
62
+ SubjectIdentifier.find(:all).each do |si|
63
+ si.update_attribute :topic_map_id, si.topic.topic_map_id
64
+ end
65
+
66
+ rename_table "qtm_subjectidentifier", "subject_identifiers"
67
+ rename_column :subject_identifiers, "locator", "reference"
68
+ add_column :subject_identifiers, :topic_map_id, :integer
69
+
70
+ SubjectIdentifier.reset_column_information
71
+ SubjectIdentifier.find(:all).each do |si|
72
+ si.update_attribute :topic_map_id, si.topic.topic_map_id
73
+ end
74
+
75
+ rename_table "qtm_subjectlocator", "subject_locators"
76
+ rename_column :subject_locators, "locator", "reference"
77
+ add_column :subject_locators, :topic_map_id, :integer
78
+
79
+ Topic.reset_column_information
80
+ SubjectLocator.reset_column_information
81
+ SubjectLocator.find(:all).each do |si|
82
+ si.update_attribute :topic_map_id, si.topic.topic_map_id
83
+ end
84
+
85
+ create_table :scoped_objects_topics do |t|
86
+ t.column :scoped_object_id, :integer
87
+ t.column :scoped_object_type, :string
88
+ t.column :topic_id, :integer
89
+ end
90
+
91
+ # TODO: instance of
92
+ # scope
93
+ # reifier
94
+ end
95
+
96
+ def self.down
97
+ raise "not supported"
98
+ end
99
+
100
+ end
101
+ end
102
+ end
103
+ end
104
+
105
+ #if __FILE__ == $0
106
+ # puts "Generating SQLite3 Databse tmdm.sqlite3."
107
+ # ActiveRecord::Base.establish_connection(
108
+ # :adapter => "sqlite3",
109
+ # :database => "tmdm.sqlite3"
110
+ # )
111
+ # RTM::AR::TMDM::QuaaxTM2RTM.migrate(:up)
112
+ #end
113
+
@@ -0,0 +1,134 @@
1
+ require 'active_record'
2
+
3
+
4
+ module RTM
5
+ module AR
6
+ module TMDM
7
+ class Topic < ActiveRecord::Base;end
8
+ class ItemIdentifier < ActiveRecord::Base
9
+ belongs_to :topic_map_construct
10
+ end
11
+ class SubjectIdentifier < ActiveRecord::Base
12
+ belongs_to :topic
13
+ end
14
+
15
+ class SubjectLocator < ActiveRecord::Base
16
+ belongs_to :topic
17
+ end
18
+
19
+ class QuaaxTM2RTMViews < ActiveRecord::Migration
20
+ def self.up
21
+ create_view "topic_maps", "select id, baselocator from qtm_topicmap" do |t|
22
+ t.column :id
23
+ t.column :base_locator
24
+ end
25
+
26
+ create_view "topics", "select id, topicmap_id, null, null from qtm_topic" do |t|
27
+ t.column :id
28
+ t.column :topic_map_id
29
+ t.column :reified_id
30
+ t.column :reified_type
31
+ end
32
+
33
+ create_view "associations", "select id, topicmap_id, type_id from qtm_association" do |t|
34
+ t.column :id
35
+ t.column :topic_map_id
36
+ t.column :ttype_id
37
+ end
38
+
39
+ create_view "association_roles", "select id, association_id, type_id, reference from qtm_assocrole" do |t|
40
+ t.column :id
41
+ t.column :association_id
42
+ t.column :ttype_id
43
+ t.column :topic_id
44
+ end
45
+
46
+ create_view "topic_names", "select id, topic_id, type_id, value from qtm_topicname" do |t|
47
+ t.column :id
48
+ t.column :topic_id
49
+ t.column :ttype_id
50
+ t.column :value
51
+ end
52
+
53
+ create_view "occurrence", "select id, topic_id, type_id, value, datatype from qtm_occurrence" do |t|
54
+ t.column :id
55
+ t.column :topic_id
56
+ t.column :ttype_id
57
+ t.column :value
58
+ t.column :datatype
59
+ end
60
+
61
+ create_view "variants", "select id, topicname_id, value, datatype from qtm_variant" do |t|
62
+ t.column :id
63
+ t.column :topic_name_id
64
+ t.column :value
65
+ t.column :datatype
66
+ end
67
+
68
+ rename_table "qtm_topicmapconstructref", "item_identifiers"
69
+ rename_column "item_identifiers", "locator", "reference"
70
+ add_column :item_identifiers, :topic_map_id, :integer
71
+ ItemIdentifier.reset_column_information
72
+ ItemIdentifier.find(:all).each do |si|
73
+ si.update_attribute :topic_map_id, si.topic_map_construct.topic_map_id
74
+ end
75
+
76
+ create_table :item_identifiers do |t|
77
+ t.column :topic_map_id, :integer, :null => false
78
+ t.column :reference, :string, :null => false
79
+ t.column :topic_map_construct_id, :integer
80
+ t.column :topic_map_construct_type, :string
81
+ end
82
+ SubjectIdentifier.reset_column_information
83
+ SubjectIdentifier.find(:all).each do |si|
84
+ si.update_attribute :topic_map_id, si.topic.topic_map_id
85
+ end
86
+
87
+ rename_table "qtm_subjectidentifier", "subject_identifiers"
88
+ rename_column :subject_identifiers, "locator", "reference"
89
+ add_column :subject_identifiers, :topic_map_id, :integer
90
+
91
+ SubjectIdentifier.reset_column_information
92
+ SubjectIdentifier.find(:all).each do |si|
93
+ si.update_attribute :topic_map_id, si.topic.topic_map_id
94
+ end
95
+
96
+ rename_table "qtm_subjectlocator", "subject_locators"
97
+ rename_column :subject_locators, "locator", "reference"
98
+ add_column :subject_locators, :topic_map_id, :integer
99
+
100
+ Topic.reset_column_information
101
+ SubjectLocator.reset_column_information
102
+ SubjectLocator.find(:all).each do |si|
103
+ si.update_attribute :topic_map_id, si.topic.topic_map_id
104
+ end
105
+
106
+ create_table :scoped_objects_topics do |t|
107
+ t.column :scoped_object_id, :integer
108
+ t.column :scoped_object_type, :string
109
+ t.column :topic_id, :integer
110
+ end
111
+
112
+ # TODO: instance of
113
+ # scope
114
+ # reifier
115
+ end
116
+
117
+ def self.down
118
+ raise "not supported"
119
+ end
120
+
121
+ end
122
+ end
123
+ end
124
+ end
125
+
126
+ #if __FILE__ == $0
127
+ # puts "Generating SQLite3 Databse tmdm.sqlite3."
128
+ # ActiveRecord::Base.establish_connection(
129
+ # :adapter => "sqlite3",
130
+ # :database => "tmdm.sqlite3"
131
+ # )
132
+ # RTM::AR::TMDM::QuaaxTM2RTM.migrate(:up)
133
+ #end
134
+