rtm 0.1.0 → 0.1.1

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.
@@ -41,1354 +41,13 @@ end
41
41
  module RTM::AR
42
42
  require 'uri'
43
43
  require 'rtm/backend/active_record/tmdm'
44
-
45
- class TMDelegator
46
- def initialize(obj)
47
- @obj = obj
48
- end
49
-
50
- def __getobj__
51
- @obj
52
- end
53
-
54
- def __setobj__(obj)
55
- @obj = obj
56
- end
57
-
58
- def self.delegate(sym, options={})
59
- to = options[:to] || sym
60
- module_eval(<<-EOS, "(__TMDELEGATOR__)", 1)
61
- def #{sym}(*args, &block)
62
- __getobj__.send(:#{to}, *args, &block)
63
- end
64
- EOS
65
-
66
- if options[:rw]
67
- module_eval(<<-EOS, "(__TMDELEGATOR2__)", 1)
68
- def #{sym}=(*args, &block)
69
- __getobj__.send(:#{to}=, *args, &block)
70
- #{options[:save] ? "__getobj__.save" : "" }
71
- end
72
- EOS
73
- end
74
-
75
- if options[:aka]
76
- options[:aka] = [options[:aka]] unless options[:aka].respond_to? :each
77
- options[:aka].each do |aka|
78
- module_eval(<<-EOS, "(__TMDELEGATOR3__)", 1)
79
- alias :#{aka} :#{sym}
80
- EOS
81
-
82
- if options[:rw]
83
- module_eval(<<-EOS, "(__TMDELEGATOR3__)", 1)
84
- alias :#{aka}= :#{sym}=
85
- EOS
86
- end
87
- end
88
- end
89
- end
90
-
91
- def self.class_delegate(sym, options={})
92
- module_eval(<<-EOS, "(__TMDELEGATOR__)", 1)
93
- class << self
94
- def #{sym}(*args, &block)
95
- __getobj__.send(:#{sym}, *args, &block)
96
- end
97
- end
98
- EOS
99
-
100
- if options[:aka]
101
- options[:aka] = [options[:aka]] unless options[:aka].respond_to? :each
102
- options[:aka].each do |aka|
103
- module_eval(<<-EOS, "(__TMDELEGATOR2__)", 1)
104
- class << self
105
- alias :#{aka} :#{sym}
106
- end
107
- EOS
108
- end
109
- end
110
- end
111
-
112
- def self.parent(sym, options={})
113
- module_eval(<<-EOS, "(__TMDELEGATOR__)", 1)
114
- def #{sym}
115
- TopicMapConstruct.wrap(__getobj__.send(:#{sym}))
116
- end
117
- EOS
118
- aka_property(sym, [:parent, :p])
119
- end
120
-
121
- def self.property_set(prop, options={})
122
- # puts "In #{self.name.to_s.ljust(20)} we have type #{options[:type].to_s.ljust(20)} for property #{prop}"
123
- if options[:wrap]
124
- #puts "#{self}: #{options[:type]}"
125
- module_eval(<<-EOS, "(__AR_DELEGATOR_PROPERTY_SET_W__)", 1)
126
- def #{prop}(*args)
127
- if args.size == 0
128
- # fetch normal
129
- #{options[:type]}s.wrap(__getobj__.#{prop}, self, :#{options[:type]})
130
- else
131
- # fetch with filter
132
- #puts args.inspect
133
- # TODO enhance/fix condition transform code
134
- a = {}.merge(args.first)
135
- if a[:type] && !a[:ttype]
136
- a[:ttype] = a[:type]
137
- a.delete(:type)
138
- end
139
- a.each do |k,v|
140
- if v.respond_to?(:__getobj__)
141
- a[(k.to_s + "_id").to_sym] = v.id
142
- end
143
- end
144
- #{options[:type]}s.wrap(__getobj__.#{prop}.find(:all, :conditions=> a), self, :#{options[:type]})
145
- end
146
- end
147
- EOS
148
- else
149
- module_eval(<<-EOS, "(__AR_DELEGATOR_PROPERTY_SET_NW__)", 1)
150
- def #{prop}
151
- __getobj__.#{prop}
152
- end
153
- EOS
154
- end
155
-
156
- if options[:create]
157
- # some :create_args:
158
- #
159
- # create_locator reference:string
160
- # [ :name => :reference, :type => :String]
161
- #
162
- # create_topic_name value:String, scope:Collection
163
- # create_topic_name value:String, type: Topic, scope:Collection
164
- # [ {:name => :value, :type => :String}, {:name => :type, :type => :Topic, :optional => true}, {:name => :scope, :type => :Collection} ]
165
- #
166
- # create_occurrence value:String, type: Topic, scope:Collection
167
- # create_occurrence resource: Locator, type: Topic, scope:Collection
168
- # [ {:name => :value, :type => [:String, :Locator]}, {:name => :type, :type => :Topic}, {:name => :scope, :type => :Collection} ]
169
- #
170
- # create_association_role player:topic, type: topic
171
- # [ {:name => :player, :type => :Topic}, {:name => :type, :type => :Topic}]
172
- #
173
- # create_variant value:string, :scope:Collection
174
- # create_variant resource:locator, :scope:Collection
175
- # [ {:name => :value, :type => [:String, :Locator]}, {:name => :scope, :type => :Collection}]
176
-
177
- module_eval(<<-EOS, "(__AR_DELEGATOR_PROPERTY_SET_CREATE__)", 1)
178
- def create_#{ options[:create]}(*args, &block)
179
- arg_defs = #{ (options[:create_args] || nil ).inspect}
180
-
181
- a = parse_args(args, arg_defs)
182
-
183
- a = enhance_args_hash(a, arg_defs) if arg_defs
184
-
185
- a = a.reject{|k,v| v.nil?}
186
-
187
- # hack to change :type to :ttype for AR backend
188
- # puts a.inspect unless a.is_a? Hash
189
- if a[:type] && !a[:ttype]
190
- a[:ttype] = a[:type]
191
- a.delete(:type)
192
- end
193
- if [:Locator,:ItemIdentifier, :SubjectIdentifier, :SubjectLocator].include?(:#{options[:type]})
194
- unless a[:topic_map]
195
- a[:topic_map] = topic_map.__getobj__
196
- end
197
- end
198
-
199
- if block_given?
200
- obj = #{options[:type]}.wrap( __getobj__.#{options[:create]}s.new(a) )
201
- yield obj
202
- obj.save
203
- else
204
- obj = #{options[:type]}.wrap( __getobj__.#{options[:create]}s.create(a) )
205
- end
206
- obj
207
- end
208
- EOS
209
-
210
- if options[:create_aka]
211
- aka_property("create_#{options[:create]}", options[:create_aka])
212
- end
213
- end
214
-
215
- if options[:add]
216
- module_eval(<<-RUBY, "(__AR_DELEGATOR_PROPERTY_SET_ADD__)", 1)
217
- def add_#{prop.to_s.singularize}(*args, &block)
218
- #{prop}.add(*args, &block)
219
- end
220
- RUBY
221
- aka_property("add_#{prop.to_s.singularize}", options[:aka].map{|a| "add_#{a}"})
222
- aka_property("add_#{prop.to_s.singularize}", options[:aka].map{|a| "a#{a}"})
223
- end
224
-
225
- if options[:remove]
226
- module_eval(<<-RUBY, "(__AR_DELEGATOR_PROPERTY_SET_REMOVE__)", 1)
227
- def remove_#{prop.to_s.singularize}(*args, &block)
228
- #{prop}.remove(*args, &block)
229
- end
230
- RUBY
231
- aka_property("remove_#{prop.to_s.singularize}", options[:aka].map{|a| "remove_#{a}"})
232
- aka_property("remove_#{prop.to_s.singularize}", options[:aka].map{|a| "r#{a}"})
233
- end
234
-
235
- # TODO: aliases for property_set.add as add_property
236
-
237
- aka_property(prop, options[:aka]) if options[:aka]
238
- end
239
-
240
- private
241
- def parse_args(args, arg_defs)
242
- a = {}
243
- a = args.pop if args.last.is_a? Hash
244
- # We are finished if there are no more parameters or we have no arg_def.
245
- # Special case: non optional parameters must have been in the Hash, just a hash is also allowed.
246
- return a if args.size == 0 || arg_defs == nil
247
-
248
- # we have some args
249
- if args.size == arg_defs.size # all are given
250
- return args2hash(a, args,arg_defs)
251
- elsif args.size == arg_defs.reject { |d| d[:optional]}
252
- return args2hash(a, args, arg_defs.reject {|d| d[:optional]})
253
- end
254
- #warn("Functions with more than one optional parameter are not supported. This will only work if the left out ones are the last.")
255
- return args2hash(a, args,arg_defs)
256
- end
257
-
258
- def args2hash(a, args, arg_defs)
259
- arg_defs.zip(args) do |argd,arg|
260
- a[argd[:name]] = arg
261
- end
262
-
263
- return a
264
- end
265
-
266
- def enhance_args_hash(a, arg_defs)
267
- #puts "enhance_args: #{a.inspect} ---\n#{arg_defs.inspect}"
268
- return a if a.empty?
269
- arg_defs.each do |argd|
270
- #puts "enhancing #{argd[:name]}, which is a #{a[argd[:name]].class}"
271
- if argd[:type] == :Topic
272
- if a[argd[:name]].is_a? String
273
- a[argd[:name]] = topic_map._topic_by_locator!(a[argd[:name]])
274
- elsif a[argd[:name]].is_a?(RTM::Topic)
275
- a[argd[:name]] = a[argd[:name]].__getobj__
276
- end
277
- end
278
- if argd[:type] == :Locator || (argd[:type].respond_to?(:include?) && argd[:type].include?(:Locator))
279
- a[argd[:name]] = a[argd[:name]].to_s
280
- end
281
- end
282
- a
283
- end
284
-
285
- public
286
- def self.property(prop, options={})
287
- module_eval(<<-EOS, "(__AR_DELEGATOR_PROPERTY__)", 1)
288
- def #{prop}
289
- #{options[:wrap]? "#{options[:type]}.wrap":""}( __getobj__.#{prop})
290
- end
291
- EOS
292
-
293
- if options[:rw]
294
- case options[:type]
295
- when :Topic
296
- module_eval(<<-EOS, "(__AR_DELEGATOR_PROPERTY2__)", 1)
297
- def #{prop}=(obj)
298
- obj = topic_map.topic_by_locator!(obj) unless obj.is_a? #{options[:type]}
299
- __getobj__.#{prop} = obj.__getobj__
300
- __getobj__.save
301
- end
302
- EOS
303
- when :TopicMap
304
- module_eval(<<-EOS, "(__AR_DELEGATOR_PROPERTY2__)", 1)
305
- def #{prop}=(obj)
306
- obj = RTM.create obj.to_s unless obj.is_a? #{options[:type]}
307
- __getobj__.#{prop} = obj.__getobj__
308
- __getobj__.save
309
- end
310
- EOS
311
- when :String, :Locator
312
- module_eval(<<-EOS, "(__AR_DELEGATOR_PROPERTY2__)", 1)
313
- def #{prop}=(obj)
314
- __getobj__.#{prop} = obj.to_s
315
- __getobj__.save
316
- end
317
- EOS
318
- else
319
- raise "Don't know how to do wrapping for #{options[:type]}"
320
- end
321
-
322
- end
323
-
324
- aka_property(prop, options[:aka]) if options[:aka]
325
- end
326
-
327
- def self.aka_property(prop, aka)
328
- aka = [aka].flatten
329
- aka.each do |a|
330
- #puts "generating alias #{a} for #{prop}"
331
- module_eval(<<-EOS, "(__AR_DELEGATOR_AKA_PROPERTY__)", 1)
332
- alias :#{a} :#{prop}
333
- EOS
334
- end
335
- end
336
-
337
- def self.index_property_set(prop, options={})
338
- r = options[:rule]
339
- module_eval(<<-EOS, "(__AR_DELEGATOR_INDEX_PROPERTY_SET__)", 1)
340
- def direct_#{prop}_roles
341
- # prefetch typing topics
342
- rtype = @ips_#{prop}_rtype ||= self.topic_map.get("#{r[:role_type]}")
343
- atype = @ips_#{prop}_atype ||= self.topic_map.get("#{r[:association_type]}")
344
- otype = @ips_#{prop}_otype ||= self.topic_map.get("#{r[:other_role_type]}")
345
- # return nothing if any of the typing topics does not exist
346
- return [] unless rtype && atype && otype
347
- # we do that only here and not earlier because some might me nil
348
- rtype = rtype.id
349
- atype = atype.id
350
- otype = otype.id
351
- self.__getobj__.roles.map{|r|
352
- r.ttype_id != nil &&
353
- r.ttype_id == rtype &&
354
- r.parent.roles.size == #{r[:association_arity]} &&
355
- r.parent != nil &&
356
- r.parent.ttype_id == atype &&
357
- (r2 = r.parent.roles.select{|r2| r2.ttype_id != nil &&
358
- r2.ttype_id == otype}.first) &&
359
- r2}.select{|r2| r2}.map{|r2| AssociationRole.wrap(r2)}
360
- end
361
- def direct_#{prop}
362
- direct_#{prop}_roles.map{|r2| r2.player}.uniq
363
- end
364
- EOS
365
-
366
- if r[:transitive]
367
- module_eval(<<-EOS, "(__AR_DELEGATOR_INDEX_PROPERTY_SET2__)", 1)
368
- def #{prop}
369
- d = todo = self.direct_#{prop}
370
- while todo.size > 0
371
- todo = todo.map{|dt| dt.direct_#{prop}}.flatten.uniq - d
372
- d += todo
373
- end
374
- d
375
- #d2 = self.direct_#{prop}.map {|dt| dt.#{prop}}.flatten
376
- #(d+d2).uniq
377
- end
378
- EOS
379
- else
380
- if r[:infer]
381
- module_eval(<<-EOS, "(__AR_DELEGATOR_INDEX_PROPERTY_SET3__)", 1)
382
- def #{prop}
383
- (self.direct_#{prop} + self.#{r[:infer]}.map{|d2| d2.direct_#{prop}}).flatten.uniq
384
- end
385
- EOS
386
- elsif r[:infer_other]
387
- module_eval(<<-EOS, "(__AR_DELEGATOR_INDEX_PROPERTY_SET4__)", 1)
388
- def #{prop}
389
- d = self.direct_#{prop}
390
- (d + d.map{|d2| d2.#{r[:infer_other]}}).flatten.uniq
391
- end
392
- EOS
393
- end
394
- end
395
- if r[:add]
396
- module_eval(<<-EOS, "(__AR_DELEGATOR_INDEX_PROPERTY_SET5__)", 1)
397
- def add_#{r[:add]}(t)
398
- a = self.topic_map.create_association("#{r[:association_type]}")
399
- a.create_role self, "#{r[:role_type]}"
400
- a.create_role t, "#{r[:other_role_type]}"
401
- a
402
- # TODO add_x in index_property_set needs to trigger reload of the topics somewhere
403
- end
404
- def remove_#{r[:add]}(t)
405
- direct_#{prop}_roles.select{|r| r.player == t}.each{|r| r.parent.remove}
406
- # TODO remove_x in index_property_set needs to trigger reload of the topics somewhere
407
- end
408
- EOS
409
- end
410
- end
411
-
412
- def self.equality(eqfields, options={})
413
- field_condition = eqfields.map {|f| "self.#{f} == o.#{f}" }.join(" && ")
414
- module_eval(<<-EOS, "(__AR_EQUALITY__)", 1)
415
- def ==(o)
416
- return false unless o
417
- return true if #{field_condition}
418
- false
419
- end
420
- EOS
421
- end
422
- def eql?(o)
423
- return false unless o
424
- return true if self.class == o.class && self.id == o.id
425
- false
426
- end
427
- def hash
428
- return self.id.hash
429
- end
430
-
431
- def self.wrapper_cache
432
- module_eval(<<-EOS, "(__AR_WRAPPER_CACHE__)", 1)
433
- def self.wrap(obj)
434
- return nil unless obj
435
- raise "Double wrapping" if obj.respond_to?(:__getobj__)
436
- t = self.wrapped(obj)
437
- if t
438
- t.__setobj__(obj)
439
- return t
440
- end
441
- self.new(obj)
442
- end
443
-
444
- def self.wrapped(unwrapped_obj)
445
- @@wrapped ||= {}
446
- return @@wrapped[unwrapped_obj.id] if unwrapped_obj.respond_to? :id
447
- @@wrapped[unwrapped_obj]
448
- end
449
- def self.reset_wrapped
450
- @@wrapped = {}
451
- end
452
- def initialize(*args)
453
- super
454
- @@wrapped ||= {}
455
- @@wrapped[self.id]=self
456
- end
457
- EOS
458
- end
459
-
460
- alias :i :id
461
- delegate :reload
462
- end
463
-
464
- class TMSetDelegator < TMDelegator
465
- include Enumerable
466
- # attr_reader :content_class_name
467
- def initialize(obj,parent,type)
468
- @obj = obj
469
- @parent = parent
470
- @type = type
471
- end
472
-
473
- # This class method wraps a Set completely while the instance method wraps one single contained object
474
- def self.wrap(obj, parent=nil, type=nil)
475
- return nil unless obj
476
- raise "Double wrapping" if obj.respond_to?(:__getobj__)
477
- self.new(obj, parent, type)
478
- end
479
-
480
- def add(obj)
481
- return unless obj
482
-
483
- old = @obj.detect { |x| x == obj } # can't that be done easier?
484
- if old
485
- old.merge obj
486
- else
487
- if obj.respond_to? :__getobj__
488
- @obj << obj.__getobj__
489
- else
490
- case @type
491
- when :Topic
492
- @obj << @parent.topic_map.get!(obj).__getobj__
493
- @parent.__getobj__.reload
494
-
495
- when :ItemIdentifier
496
- if @parent.class.name.to_s =~ /::Topic$/
497
- tbi = @parent.topic_map._item_identifier(obj)
498
- if tbi && tmc=tbi.topic_map_construct
499
- if tmc.class.name =~ /::Topic$/
500
- return @parent if tmc == @parent.__getobj__
501
- result = Topic.wrap(tmc).merge @parent
502
- return result
503
- else
504
- raise "Duplicate Item Identifier"
505
- end
506
- end
507
- tbsi = @parent.topic_map._subject_identifier(obj.to_s)
508
- if tbsi
509
- if t=tbsi.topic
510
- return @parent if t == @parent.__getobj__
511
- result = Topic.wrap(t).merge @parent
512
- # after merging, we still need to add the II
513
- result.__getobj__.item_identifiers.create(:reference => obj.to_s, :topic_map_id => @parent.topic_map.__getobj__.id)
514
- return result
515
- end
516
- end
517
- end
518
- result = @obj << @parent.topic_map._item_identifier!(obj.to_s)
519
- return result
520
-
521
- when :SubjectIdentifier
522
- # check for existing item identifier
523
- tbi = @parent.topic_map._item_identifier(obj)
524
- if tbi && tmc=tbi.topic_map_construct
525
- if tmc.class.name =~ /::Topic$/
526
- return @parent if tmc == @parent.__getobj__
527
- result = Topic.wrap(tmc).merge @parent
528
- # after merging, we still need to add the SI
529
- result.__getobj__.subject_identifiers.create(:reference => obj.to_s, :topic_map_id => @parent.topic_map.__getobj__.id)
530
- return result
531
- else
532
- warn("This subject identifier IRI already belongs to another topic map construct (not a topic)")
533
- end
534
- end
535
- # check for existing subject identifier
536
- tbsi = @parent.topic_map._subject_identifier(obj.to_s)
537
- if tbsi
538
- if true && t=tbsi.topic #the single = is intentional, the "true &&" just makes netbeans not raise a warning
539
- return @parent if t == @parent.__getobj__
540
- result = Topic.wrap(t).merge @parent
541
- return result
542
- end
543
- end
544
- @obj.create(:reference => obj.to_s, :topic_map_id => @parent.topic_map.__getobj__.id)
545
-
546
- when :SubjectLocator
547
- tbsl = @parent.topic_map._subject_locator(obj.to_s)
548
- if tbsl
549
- if true && t=tbsl.topic #the single = is intentional, the "true &&" just makes netbeans not raise a warning
550
- return @parent if t == @parent.__getobj__
551
- result = Topic.wrap(t).merge @parent
552
- return result
553
- end
554
- end
555
- @obj.create(:reference => obj.to_s, :topic_map_id => @parent.topic_map.__getobj__.id)
556
-
557
- end
558
- end
559
- end
560
- end
561
- alias :<< :add
562
-
563
- def add_all(objs)
564
- return unless objs
565
- objs.each {|obj| add(obj)}
566
- true
567
- end
568
-
569
- def each(&b)
570
- @obj.each { |e| yield wrap(e)}
571
- end
572
-
573
- def size
574
- @obj.size
575
- end
576
- alias :length :size
577
-
578
- def empty?
579
- @obj.empty?
580
- end
581
-
582
- def delete(obj)
583
- obj = obj.__getobj__ if obj.respond_to? :__getobj__
584
- case @type
585
- when :ItemIdentifier, :SubjectIdentifier, :SubjectLocator
586
- obj = @obj.find_by_reference(@parent.topic_map.resolve(obj.to_s)) if obj.is_a? String
587
- end
588
- @obj.delete(obj)
589
- # item_identifiers: remove also from topicMap
590
- #removed_event obj if respond_to? :removed_event
591
- end
592
- alias :remove :delete
593
-
594
- def include?(obj)
595
- return @obj.include?(obj)
596
- #@obj.each { |e| return true if e == obj } # T#ODO support for get
597
- #false
598
- end
599
-
600
- def first
601
- wrap(@obj.entries.first)
602
- end
603
- def last
604
- wrap(@obj.entries.last)
605
- end
606
-
607
- def to_s
608
- "[#{@obj.entries.map { |e| wrap(e).to_s }.join(", ") }]"
609
- end
610
- def [](i)
611
- wrap(@obj[i])
612
- end
613
-
614
- def content_class
615
- # @content_class ||= RTM.const_get(@content_class_name)
616
- @content_class ||= RTM.const_get("#{@content_class_name}MemImpl")
617
- end
618
-
619
- def find(*args)
620
- res = @obj.find(*args)
621
- if res.respond_to? :each
622
- TopicMapConstructs.wrap(res)
623
- else
624
- TopicMapConstruct.wrap(res)
625
- end
626
- end
627
-
628
- def &(other)
629
- @obj.to_a & other.to_a
630
- end
631
-
632
- alias :old_method_missing :method_missing
633
- def method_missing(method_name, *args)
634
- if @obj.size > 0 && first.respond_to?(method_name) && (![:__getobj__, :__setobj__].include?(method_name))
635
- a = []
636
- inject(a) {|all,single| all << single.send(method_name, *args)}
637
- a
638
- else
639
- old_method_missing(method_name, *args)
640
- end
641
- end
642
-
643
- alias :old_respond_to? :respond_to?
644
- def respond_to?(method_name)
645
- resp = old_respond_to?(method_name)
646
- return resp if resp # i.e. if true
647
- return false if [:__getobj__, :__setobj__].include?(method_name)
648
- # ... and ask first child otherwise
649
- @obj.size > 0 && first.respond_to?(method_name)
650
- end
651
-
652
- # TMSetDelegator#to_a doesn't help as thought, but maybe we come back to that l8r...
653
- #def to_a
654
- # @obj.map {|o| wrap(o)}
655
- #end
656
- end
657
-
658
- class TopicMapConstruct < TMDelegator
659
- include RTM::TopicMapConstruct
660
-
661
- def self.abstract_class?
662
- self == TopicMapConstruct
663
- end
664
- property_set :item_identifiers, :aka => [:ii, :iid, :source_locators], :type => :ItemIdentifier, :wrap => true,
665
- #:create => :item_identifier, :create_aka => :cii
666
- :add => true, :remove => true
667
-
668
- delegate :remove, :to => :destroy
669
-
670
- delegate :id
671
- # property_parent :parent # mmh..
672
-
673
- property :topic_map, :rw => true, :type => :TopicMap, :wrap => true
674
-
675
- #class_delegate :create
676
-
677
- def self.wrap(obj)
678
- return nil unless obj
679
- raise "Double wrapping" if obj.respond_to?(:__getobj__)
680
- case obj.class.name
681
- when "RTM::AR::TMDM::Topic"
682
- Topic.wrap(obj)
683
- when "RTM::AR::TMDM::Variant"
684
- Variant.wrap(obj)
685
- when "RTM::AR::TMDM::TopicName"
686
- TopicName.wrap(obj)
687
- when "RTM::AR::TMDM::Occurrence"
688
- Occurrence.wrap(obj)
689
- when "RTM::AR::TMDM::Association"
690
- Association.wrap(obj)
691
- when "RTM::AR::TMDM::AssociationRole"
692
- AssociationRole.wrap(obj)
693
- when "RTM::AR::TMDM::TopicMap"
694
- TopicMap.wrap(obj)
695
- else
696
- raise "Can't wrap object. Class for wrapping #{obj.class} unknown (object: #{obj})"
697
- end
698
- end
699
-
700
- def self.find(*args)
701
- res = RTM::AR::TMDM.const_get(name.split("::").last).find(*args)
702
- if res.respond_to? :each
703
- TopicMapConstructs.wrap(res)
704
- else
705
- TopicMapConstruct.wrap(res)
706
- end
707
- end
708
- end
709
-
710
- class Reifiable < TopicMapConstruct
711
- include RTM::Reifiable
712
-
713
- def self.abstract_class?
714
- self == Reifiable
715
- end
716
- property :reifier, :type => :Topic, :rw => :true, :wrap => true
717
- end
718
-
719
- class TopicMap < Reifiable
720
- include RTM::TopicMap
721
- wrapper_cache
722
- property_set :topics, :aka => :t, :type => :Topic, :wrap => true,
723
- :create => :topic, :create_aka => :ct
724
-
725
- property_set :associations, :aka => [:a, :assocs], :type => :Association, :wrap => true,
726
- :create => :association, :create_aka => :ca,
727
- :create_args => [{:name => :type, :type => :Topic}]
728
-
729
-
730
- delegate :base_locator
731
-
732
- property_set :association_types, :aka => :at, :type => :Topic, :wrap => true
733
- property_set :association_role_types, :aka => [:role_types,:art,:rt], :type => :Topic, :wrap => true
734
- property_set :topic_name_types, :aka => [:name_types,:tnt,:nt], :type => :Topic, :wrap => true
735
- property_set :occurrence_types, :aka => :ot, :type => :Topic, :wrap => true
736
-
737
- property_set :topic_names, :aka => [:names,:n], :type => :TopicName, :wrap => :true
738
- property_set :occurrences, :aka => :o, :type => :Occurrence, :wrap => :true
739
- property_set :association_roles, :aka => [:roles, :r], :type => :AssociationRole, :wrap => :true
740
-
741
- def types
742
- topics.select{|t| t.instances.size > 0}
743
- end
744
- alias :topic_types :types
745
- def fast_types
746
-
747
- end
748
-
749
- # This fetches all topics who have no topic-instances (but they might be types for associations etc.).
750
- # See indivduals
751
- def non_types
752
- topics.select{|t| t.instances.size == 0}
753
- end
754
-
755
- # This fetches all topics which are not type for something else (including topics, associations etc.).
756
- # See non_types
757
- def individuals
758
- non_types.select{|t| t.associations_typed.size==0 && t.roles_typed.size==0 && t.names_typed.size==0 && t.occurrences_typed.size==0}
759
- end
760
- def instances
761
- topics.select{|t| t.types.size > 0}
762
- end
763
- def non_instances
764
- topics.reject{|t| t.types.size > 0}
765
- end
766
- def internal_occurrences
767
- occurrences.select{|o| o.datatype != RTM::PSI[:IRI]}
768
- end
769
- def external_occurrences
770
- occurrences.select{|o| o.datatype == RTM::PSI[:IRI]}
771
- end
772
-
773
- def self.create(base_locator, params={})
774
- tm = self.wrap(TMDM::TopicMap.find_or_create_by_base_locator(base_locator))
775
- yield tm if block_given?
776
- tm
777
- end
778
-
779
- def self.topic_maps
780
- TopicMaps.wrap(TMDM::TopicMap.find(:all))
781
- end
782
-
783
- # Resolves an IRI or fragment relative to the base_locator of this topic_map or an optional given alternative_base_locator
784
- #
785
- # Absolute IRIs are taken as is.
786
- #
787
- # Relative IRIs:
788
- # If the base_locator is a directory (ends with "/") it is appended like a file, i.e. directly
789
- # If the base_locator is a file it is appended as a fragment (with # in between)
790
- def resolve(obj,alternative_base_locator=nil)
791
- uri = obj.to_s
792
- # TODO uri = URI.decode(obj.to_s) # this InvalidURIError somethimes :(
793
- begin
794
- uri_uri = URI.parse(uri)
795
- rescue URI::InvalidComponentError => ice
796
- warn "Catched an URI::InvalidComponentError for URI: #{uri}, message was \"#{ice.message}\"\n" +
797
- "Will continue using the UNRESOLVED IRI, claiming it is absolute."
798
- return uri
799
- end
800
- if uri_uri.absolute?
801
- return uri_uri.to_s
802
- end
803
-
804
- uri = uri[1..-1] if uri[0] == "#"[0]
805
- bl = alternative_base_locator || base_locator
806
- if bl[-1,1] == "/"
807
- return bl + uri
808
- else
809
- return bl + "#" + uri
810
- end
811
- end
812
-
813
- #private
814
-
815
- def _item_identifier(iid)
816
- __getobj__.locators.find_by_reference(resolve(iid)) # doesn't work :( --> , :include => [ :topic_map_construct ])
817
- end
818
- def _item_identifier!(iid)
819
- __getobj__.locators.find_or_create_by_reference(resolve(iid)) # doesn't work :( --> , :include => [ :topic_map_construct ])
820
- end
821
-
822
- def _subject_identifier(iid)
823
- __getobj__.subject_identifiers.find_by_reference(iid, :include => :topic)
824
- end
825
- def _subject_identifier!(iid)
826
- __getobj__.subject_identifiers.find_or_create_by_reference(iid, :include => :topic)
827
- end
828
-
829
- def _subject_locator(iid)
830
- __getobj__.subject_locators.find_by_reference(iid, :include => :topic)
831
- end
832
- def _subject_locator!(iid)
833
- __getobj__.subject_locators.find_or_create_by_reference(iid, :include => :topic)
834
- end
835
-
836
-
837
- # internal helper for by_item_identifier, doesn't wrap result
838
- def _by_item_identifier(iid)
839
- ii = __getobj__.locators.find_by_reference(resolve(iid)) #, :include => [ :topic_map_construct ])
840
- return ii.topic_map_construct if ii
841
- nil
842
- end
843
- def _topic_by_item_identifier(iid)
844
- t = _by_item_identifier(iid)
845
- return nil unless t
846
- return t if t.class.name =~ /::Topic$/ # only return something if the thing is a topic
847
- nil
848
- end
849
-
850
- # internal helper for topic_by_item_identifier!, doesn't wrap result
851
- def _topic_by_item_identifier!(iid)
852
- ii = __getobj__.locators.find_or_create_by_reference(resolve(iid))#, :include => [ :topic_map_construct ])
853
- return ii.topic_map_construct if ii.topic_map_construct && ii.topic_map_construct_type =~ /::Topic$/
854
- top2 = _topic_by_subject_identifier(resolve(iid))
855
- if top2
856
- ii.topic_map_construct = top2
857
- else
858
- ii.topic_map_construct = create_topic.__getobj__
859
- end
860
- ii.save
861
- ii.topic_map_construct
862
- end
863
- # internal helper for topic_by_subject_identifier, doesn't wrap result
864
- def _topic_by_subject_identifier(sid)
865
- si = __getobj__.subject_identifiers.find_by_reference(sid, :include => [ :topic ])
866
- return si.topic if si
867
- nil
868
- end
869
- # internal helper for topic_by_subject_identifier!, doesn't wrap result
870
- def _topic_by_subject_identifier!(sid)
871
- si = __getobj__.subject_identifiers.find_or_create_by_reference(sid, :include => [ :topic ])
872
- return si.topic if si.topic
873
- begin
874
- top2 = _by_item_identifier(sid)
875
- rescue ActiveRecord::RecordNotFound => rnf
876
- si.topic = create_topic.__getobj__
877
- else
878
- if top2 && top2.respond_to?(:subject_identifiers)
879
- si.topic = top2
880
- else
881
- si.topic = create_topic.__getobj__
882
- end
883
- end
884
- si.save
885
- si.topic
886
- end
887
-
888
- # internal helper for topic_by_subject_locator, doesn't wrap result
889
- def _topic_by_subject_locator(slo)
890
- sl = __getobj__.subject_locators.find_by_reference(RTM::LocatorHelpers.slo2iri(slo)) #, :include => [ :topic ])
891
- return sl.topic if sl
892
- nil
893
- end
894
-
895
- # internal helper for topic_by_subject_locator!, doesn't wrap result
896
- def _topic_by_subject_locator!(slo)
897
- sl = __getobj__.subject_locators.find_or_create_by_reference(RTM::LocatorHelpers.slo2iri(slo), :include => [ :topic ])
898
- return sl.topic if sl.topic
899
- sl.topic = create_topic.__getobj__
900
- sl.save
901
- sl.topic
902
- end
903
- def _topic_by_locator(iri)
904
- raise "Locator may not be nil" unless iri
905
- if RTM::LocatorHelpers.is_a_slo?(iri)
906
- _topic_by_subject_locator(iri)
907
- elsif URI.parse(iri).absolute?
908
- _topic_by_subject_identifier(iri)
909
- else
910
- _topic_by_item_identifier(iri)
911
- end
912
- end
913
-
914
- def _topic_by_locator!(iri)
915
- raise "Locator may not be nil" unless iri
916
- if RTM::LocatorHelpers.is_a_slo?(iri)
917
- _topic_by_subject_locator!(iri)
918
- elsif URI.parse(iri).absolute?
919
- _topic_by_subject_identifier!(iri)
920
- else
921
- _topic_by_item_identifier!(iri)
922
- end
923
- end
924
-
925
- public
926
- # returns an item identifier from the topic_map if it exists
927
- def item_identifier(iid)
928
- ItemIdentifier.wrap(_item_identifier(iid))
929
- end
930
- # returns an item identififier from the topic_map or creates it if it doesn't exist
931
- def item_identifier!(iid)
932
- ItemIdentifier.wrap(_item_identifier!(iid))
933
- end
934
- alias :create_locator :item_identifier!
935
- # Returns a topic map construct by it's item identifier or nil if not found.
936
- # It's the equivalent to TMAPI's TopicMapObjectIndex.getTopicMapObjectBySourceLocator
937
- def by_item_identifier(iid)
938
- TopicMapConstruct.wrap(_by_item_identifier(iid))
939
- end
940
- # Returns a topic by it's item identifier. The topic will be created if not found.
941
- def topic_by_item_identifier!(iid)
942
- Topic.wrap(_topic_by_item_identifier!(iid))
943
- end
944
- # Returns a topic by it's subject identifier or nil if not found.
945
- # It's the equivalent to TMAPI's TopicsIndex.getTopicBySubjectIdentifier.
946
- def topic_by_subject_identifier(sid)
947
- Topic.wrap(_topic_by_subject_identifier(sid))
948
- end
949
- # returns a topic by it's subject identifier. The topic will be created if not found.
950
- def topic_by_subject_identifier!(sid)
951
- Topic.wrap(_topic_by_subject_identifier!(sid))
952
- end
953
- # Returns a topic by it's subject locator or nil if not found.
954
- # It's the equivalent to TMAPI's TopicsIndex.getTopicBySubjectLocator
955
- def topic_by_subject_locator(slo)
956
- Topic.wrap(_topic_by_subject_locator(slo))
957
- end
958
- # returns a topic by it's subject locator. The topic will be created if not found.
959
- def topic_by_subject_locator!(slo)
960
- Topic.wrap(_topic_by_subject_locator!(slo))
961
- end
962
-
963
- # Gets a topic from this topic map using its (relative) item identifier,
964
- # its (absolute) subject identifier or its (absolute and by "=" prepended) subject locator)
965
- #
966
- # Returns nil if the Topic does not exist.
967
- #
968
- def topic_by_locator(iri)
969
- return iri if iri.is_a? Topic
970
- # @tblc ||= {}
971
- # t = @tblc[iri]
972
- # return t if t
973
- t = Topic.wrap(_topic_by_locator(iri))
974
- # @tblc[iri] = t if t
975
- # t
976
- end
977
- alias :get :topic_by_locator
978
-
979
- # Gets a topic from this topic map using its (relative) item identifier,
980
- # its (absolute) subject identifier or its (absolute and by "=" prepended) subject locator)
981
- #
982
- # If there is no topic with this item identifier, subject identifier or subject locator, it is created.
983
- #
984
- def topic_by_locator!(iri)
985
- return iri if iri.is_a? Topic
986
- # @tblc ||= {}
987
- # t = @tblc[iri]
988
- # return t if t
989
- t = Topic.wrap(_topic_by_locator!(iri))
990
- # @tblc[iri] = t
991
- # t
992
- end
993
- alias :get! :topic_by_locator!
994
-
995
- # I am not sure if this is at all correct. TMDM doesn't say a word about it
996
- # and the approach to compare topic maps is CXTM. I chose this because we
997
- # should (at least at the time of writing) have only one topic with a given
998
- # base locator in RTM. If you don't like it, drop me a mail and explain why
999
- # and propose something better.
1000
- equality [:base_locator]
1001
- end
1002
-
1003
- class Topic < TopicMapConstruct
1004
- include RTM::Topic
1005
- wrapper_cache
1006
-
1007
- parent :topic_map
1008
- property_set :subject_identifiers, :aka => [:si,:sid], :type => :SubjectIdentifier, :wrap => true,
1009
- #:create => :subject_identifier, :create_aka => [:csi,:csid],
1010
- #:create_args => [{:name => :reference, :type => :String}]
1011
- :add => true, :remove => true
1012
- property_set :subject_locators, :aka => [:sl,:slo], :type => :SubjectLocator, :wrap => true,
1013
- #:create => :subject_locator, :create_aka => [:csl, :cslo],
1014
- #:create_args => [{:name => :reference, :type => :String}]
1015
- :add => true, :remove => true
1016
-
1017
- property :reified, :computable => true, :type => :Reifiable, :wrap => true
1018
-
1019
- property_set :topic_names, :aka => [:n, :names], :type => :TopicName, :wrap => true,
1020
- :create => :topic_name, :create_aka => [:create_name, :cn],
1021
- :create_args => [ {:name => :value, :type => :String}, {:name => :type, :type => :Topic, :optional => true}, {:name => :scope, :type => :Collection} ]
1022
-
1023
- property_set :occurrences, :aka => :o, :type => :Occurrence, :wrap => true,
1024
- :create => :occurrence, :create_aka => :co,
1025
- :create_args => [ {:name => :value, :type => [:String, :Locator]}, {:name => :type, :type => :Topic}, {:name => :scope, :type => :Collection} ]
1026
-
1027
- def internal_occurrences
1028
- occurrences.select{|o| o.datatype != RTM::PSI[:IRI]}
1029
- end
1030
- def external_occurrences
1031
- occurrences.select{|o| o.datatype == RTM::PSI[:IRI]}
1032
- end
1033
-
1034
- property_set :roles, :aka => [:r, :roles_played, :association_roles], :computable => true, :type => :AssociationRole, :wrap => true
1035
-
1036
- property_set :associations, :aka => [:a, :associations_played], :type => :Association, :wrap => true
1037
-
1038
- property_set :scoped_objects, :type => :TopicMapConstruct, :wrap => true
1039
- property_set :scoped_associations, :type => :Association, :wrap => true
1040
- property_set :scoped_topic_names, :aka => :scoped_names, :type => :TopicName, :wrap => true
1041
- property_set :scoped_variants, :type => :Variant, :wrap => true
1042
- property_set :scoped_occurrences, :type => :Occurrence, :wrap => true
1043
-
1044
- property_set :associations_typed, :aka => :at, :type => :Association, :wrap => true
1045
- property_set :association_roles_typed, :aka => [:roles_typed,:art,:rt], :type => :AssociationRole, :wrap => true
1046
- property_set :topic_names_typed, :aka => [:names_typed,:tnt,:nt], :type => :TopicName, :wrap => true
1047
- property_set :occurrences_typed, :aka => :ot, :type => :Occurrence, :wrap => true
1048
-
1049
- # maybe these pairs could be declared each with a single statement and a reversible option
1050
- index_property_set :types, :type => :Topic, :rule => {
1051
- :transitive => false,
1052
- :role_type => RTM::PSI[:instance],
1053
- :association_type => RTM::PSI[:type_instance],
1054
- :association_arity => 2,
1055
- :other_role_type => RTM::PSI[:type],
1056
- :infer_other => :supertypes,
1057
- :add => :type,
1058
- }
1059
- index_property_set :instances, :type => :Topic, :rule => {
1060
- :transitive => false,
1061
- :role_type => RTM::PSI[:type],
1062
- :association_type => RTM::PSI[:type_instance],
1063
- :association_arity => 2,
1064
- :other_role_type => RTM::PSI[:instance],
1065
- :infer => :subtypes,
1066
- :add => :instance,
1067
- }
1068
- index_property_set :supertypes, :type => :Topic, :rule => {
1069
- :transitive => true,
1070
- :role_type => RTM::PSI[:subtype],
1071
- :association_type => RTM::PSI[:supertype_subtype],
1072
- :association_arity => 2,
1073
- :other_role_type => RTM::PSI[:supertype],
1074
- :add => :supertype,
1075
- }
1076
- index_property_set :subtypes, :type => :Topic, :rule => {
1077
- :transitive => true,
1078
- :role_type => RTM::PSI[:supertype],
1079
- :association_type => RTM::PSI[:supertype_subtype],
1080
- :association_arity => 2,
1081
- :other_role_type => RTM::PSI[:subtype],
1082
- :add => :subtype,
1083
- }
1084
-
1085
- def [](topicref)
1086
- topicref =~ /^(-\s*)?(.+)?$/
1087
- if $1
1088
- nametype = $2 || RTM::PSI[:name_type]
1089
- names.select{|n| n.type == topic_map.get(nametype)}
1090
- else
1091
- raise "No occurrence type given" unless $2 and !$2.empty?
1092
- occurrences.select{|o| o.type == topic_map.get($2)}
1093
- end
1094
- end
1095
-
1096
- def []=(topicref, value)
1097
- topicref =~ /^(-\s*)?(.+)?$/
1098
- if $1
1099
- nametype = $2 || topic_map.get!(RTM::PSI[:name_type])
1100
- n = create_name(value, nametype)
1101
- n
1102
- else
1103
- raise "No occurrence type given" unless $2
1104
- o = create_occurrence(value, $2)
1105
- o
1106
- end
1107
- end
1108
-
1109
- # class:Topic equality, http://www.isotopicmaps.org/sam/sam-model/#d0e1029
1110
- #
1111
- # This method is all crap. These ActiveRecord Arrays can't be intersected,
1112
- # so I map the identifiers to their reference which seems long winded.
1113
- # Still I find it better than using their ID in the long.
1114
- #
1115
- def ==(o)
1116
- return false unless o
1117
- # Two topic items are equal if they have:
1118
- # * at least one equal string in their [subject identifiers] properties,
1119
- # -> test if intersection are > 0
1120
- my_si = self.subject_identifiers.map{|si| si.reference}
1121
- ot_si = o.subject_identifiers.map{|si| si.reference}
1122
- return true if ( my_si & ot_si).size > 0
1123
-
1124
- # * at least one equal string in their [item identifiers] properties,
1125
- my_ii = self.item_identifiers.map{|ii| ii.reference}
1126
- ot_ii = o.item_identifiers.map{|ii| ii.reference}
1127
- return true if (my_ii & ot_ii).size > 0
1128
-
1129
- # * at least one equal string in their [subject locators] properties,
1130
- my_sl = self.subject_locators.map{|sl| sl.reference}
1131
- ot_sl = o.subject_locators.map{|sl| sl.reference}
1132
- return true if (my_sl & ot_sl).size > 0
1133
-
1134
- # * an equal string in the [subject identifiers] property of the one topic item and the [item identifiers] property of the other, or
1135
- return true if (my_si & ot_ii).size > 0
1136
- return true if (my_ii & ot_si).size > 0
1137
-
1138
- # * the same information item in their [reified] properties.
1139
- return true if self.reified != nil && o.reified != nil && (self.reified == o.reified)
1140
- # ... otherwise
1141
- false
1142
- end
1143
- end
1144
-
1145
- class Association < Reifiable
1146
- include RTM::Association
1147
- wrapper_cache
1148
-
1149
- parent :topic_map
1150
- property :type, :aka => [:ty,:t], :rw => true, :type => :Topic, :wrap => true
1151
- property_set :scope, :type => :Topic, :wrap => true
1152
- property_set :roles, :aka => [:r, :association_roles], :type => :AssociationRole, :wrap => true,
1153
- :create => :role, :create_aka => [:cr, :create_association_role],
1154
- :create_args => [ {:name => :player, :type => :Topic}, {:name => :type, :type => :Topic}]
1155
-
1156
- property_set :role_players, :aka => [:players, :rp, :pl], :type => :Topic, :wrap => true
1157
- property_set :role_types, :aka => [:types, :rt], :type => :Topic, :wrap => true
1158
-
1159
- equality [:scope, :type, :roles]
1160
- end
1161
-
1162
- class AssociationRole < Reifiable
1163
- include RTM::AssociationRole
1164
- wrapper_cache
1165
-
1166
- parent :association
1167
- property :player, :aka => [:pl,:topic], :rw => true, :type => :Topic, :wrap => true
1168
- property :type, :aka => [:ty,:t], :rw => true, :type => :Topic, :wrap => true
1169
-
1170
- def counterparts
1171
- self.parent.roles.reject{|r| r.id==self.id}
1172
- end
1173
- def counterplayers
1174
- self.counterparts.map{|r| r.player}
1175
- end
1176
- def counterpart
1177
- n = self.parent.roles.size
1178
- raise "Association must be unary or binary to use counterpart method. Please use counterparts for n-ary associations." if n > 2
1179
- return nil if n == 1
1180
- self.parent.roles.reject{|r| r.id==self.id}.first
1181
- end
1182
- def counterplayer
1183
- n = self.parent.roles.size
1184
- raise "Association must be unary or binary to use counterplayer method. Please use counterplayers for n-ary associations." if n > 2
1185
- return nil if n == 1
1186
- self.parent.roles.reject{|r| r.id==self.id}.first.player
1187
- end
1188
- def peers
1189
- self.counterpart.player.roles.select{|r| r.type == cp.type}.counterpart
1190
- end
1191
- def peerplayers
1192
- self.peers.map{|r| r.player}
1193
- end
1194
-
1195
- equality [:type, :player, :parent]
1196
- end
1197
-
1198
- class TopicName < Reifiable
1199
- include RTM::TopicName
1200
- wrapper_cache
1201
-
1202
- parent :topic
1203
- property :type, :aka => [:ty,:t], :rw => true, :type => :Topic, :wrap => true
1204
- property_set :scope, :type => :Topic, :wrap => true
1205
-
1206
- property_set :variants, :aka => :v, :type => :Variant, :wrap => true,
1207
- :create => :variant, :create_aka => :cv,
1208
- :create_args => [ {:name => :value, :type => [:String, :Locator]}, {:name => :scope, :type => :Collection}]
1209
-
1210
- property :value, :rw => true, :type => :String
1211
-
1212
- equality [:value, :type, :scope, :parent]
1213
- end
1214
-
1215
- class Occurrence < Reifiable
1216
- include RTM::Occurrence
1217
- wrapper_cache
1218
-
1219
- parent :topic
1220
- property :value, :rw => true, :type => :String
1221
- property :datatype, :rw => true, :type => :String
1222
-
1223
- property_set :scope, :type => :Topic, :wrap => true
1224
- property :type, :aka => [:ty,:t], :rw => true, :type => :Topic, :wrap => true
1225
-
1226
- equality [:value, :datatype, :scope, :type, :parent]
1227
- end
1228
-
1229
- class Variant < Reifiable
1230
- include RTM::Variant
1231
- wrapper_cache
1232
-
1233
- parent :topic_name, :aka => :name
1234
- property :value, :rw => true, :type => :String
1235
- property :datatype, :rw => true, :type => :Locator #, :wrap => true
1236
- property_set :scope, :type => :Topic, :wrap => true
1237
-
1238
- equality [:value, :datatype, :scope, :parent]
1239
-
1240
- end
1241
-
1242
- class Locator < TMDelegator
1243
- include RTM::Locator
1244
-
1245
- delegate :+
1246
- delegate :-
1247
- #delegate :==
1248
- delegate :id
1249
-
1250
- delegate :get
1251
- delegate :hash
1252
- delegate :resolve_relative
1253
- delegate :to_s, :to => :reference
1254
- delegate :to_uri
1255
- delegate :uri
1256
- delegate :reference, :rw => true, :save => true
1257
- alias :value :reference
1258
- alias :value= :reference=
1259
-
1260
- equality [:reference]
1261
-
1262
- def self.wrap(obj)
1263
- return nil unless obj
1264
- raise "Double wrapping" if obj.respond_to?(:__getobj__)
1265
- case obj.class.name
1266
- when "RTM::AR::TMDM::ItemIdentifier"
1267
- ItemIdentifier.wrap(obj)
1268
- when "RTM::AR::TMDM::SubjectIdentifier"
1269
- SubjectIdentifier.wrap(obj)
1270
- when "RTM::AR::TMDM::SubjectLocator"
1271
- SubjectLocator.wrap(obj)
1272
- else
1273
- raise "Can't wrap object. Class for wrapping #{obj.class} unknown (object: #{obj})"
1274
- end
1275
- end
1276
-
1277
-
1278
- end
1279
-
1280
-
1281
- class ItemIdentifier < Locator
1282
- include RTM::ItemIdentifier
1283
- wrapper_cache
1284
- property :topic_map_construct, :type => :TopicMapConstruct, :wrap => true
1285
- end
1286
- class SubjectIdentifier < Locator
1287
- include RTM::SubjectIdentifier
1288
- wrapper_cache
1289
- property :topic, :type => :Topic, :wrap => true
1290
- end
1291
- class SubjectLocator < Locator
1292
- include RTM::SubjectLocator
1293
- wrapper_cache
1294
- property :topic, :type => :Topic, :wrap => true
1295
- end
1296
- class Topics < TMSetDelegator
1297
- def wrap(obj)
1298
- Topic.wrap(obj)
1299
- end
1300
- end
1301
- class TopicMapConstructs < TMSetDelegator
1302
- def wrap(obj)
1303
- TopicMapConstruct.wrap(obj)
1304
- end
1305
- end
1306
- class Associations < TMSetDelegator
1307
- def wrap(obj)
1308
- Association.wrap(obj)
1309
- end
1310
- end
1311
- class TopicNames < TMSetDelegator
1312
- def wrap(obj)
1313
- TopicName.wrap(obj)
1314
- end
1315
- end
1316
- class Occurrences < TMSetDelegator
1317
- def wrap(obj)
1318
- Occurrence.wrap(obj)
1319
- end
1320
- end
1321
- class AssociationRoles < TMSetDelegator
1322
- def wrap(obj)
1323
- AssociationRole.wrap(obj)
1324
- end
1325
- end
1326
- class Reifiables < TMSetDelegator
1327
- def wrap(obj)
1328
- TopicMapConstruct.wrap(obj)
1329
- end
1330
- end
1331
- class Variants < TMSetDelegator
1332
- def wrap(obj)
1333
- Variant.wrap(obj)
1334
- end
1335
- end
1336
- class TopicMaps < TMSetDelegator
1337
- def [](obj)
1338
- # support for getting topic_map by base_locator
1339
- if obj.is_a? String
1340
- # return wrap(__getobj__.find { |tm| tm.base_locator == obj })
1341
- return wrap(TMDM::TopicMap.find_by_base_locator(obj))
1342
- end
1343
- # normal index retrieval
1344
- super
1345
- end
1346
-
1347
- def wrap(obj)
1348
- TopicMap.wrap(obj)
1349
- end
1350
- end
1351
- class Locators < TMSetDelegator
1352
- def [](obj)
1353
- # support for getting locators by reference
1354
- if obj.is_a? String
1355
- return wrap(__getobj__.find { |tm| tm.reference == obj })
1356
- end
1357
- # normal index retrieval
1358
- super
1359
- end
1360
- def wrap(obj)
1361
- return nil unless obj
1362
- return obj if obj.respond_to? :__getobj__
1363
- case obj.class.name
1364
- when "RTM::AR::TMDM::ItemIdentifier"
1365
- ItemIdentifier.wrap(obj)
1366
- when "RTM::AR::TMDM::SubjectIdentifier"
1367
- SubjectIdentifier.wrap(obj)
1368
- when "RTM::AR::TMDM::SubjectLocator"
1369
- SubjectLocator.wrap(obj)
1370
- else
1371
- Locator.wrap(obj)
1372
- end
1373
- end
1374
- end
1375
-
1376
- class ItemIdentifiers < Locators
1377
- def wrap(obj)
1378
- ItemIdentifier.wrap(obj)
1379
- end
1380
- end
1381
- class SubjectIdentifiers < Locators
1382
- def wrap(obj)
1383
- SubjectIdentifier.wrap(obj)
1384
- end
1385
-
1386
- end
1387
- class SubjectLocators < Locators
1388
- def wrap(obj)
1389
- SubjectLocator.wrap(obj)
1390
- end
1391
- end
1392
-
44
+ require 'rtm/backend/active_record/tm_delegator'
45
+ require 'rtm/backend/active_record/tm_set_delegator'
46
+ require 'rtm/backend/active_record/tm_construct'
47
+ require 'rtm/backend/active_record/topic_map'
48
+ require 'rtm/backend/active_record/topic'
49
+ require 'rtm/backend/active_record/association_and_role'
50
+ require 'rtm/backend/active_record/name_variant_occurrence'
51
+ require 'rtm/backend/active_record/locators'
52
+ require 'rtm/backend/active_record/set_wrapper'
1393
53
  end
1394
-