Class: RTM::AR::TopicMap

Inherits:
Reifiable show all
Includes:
TopicMap
Defined in:
lib/rtm/activerecord/topic_map.rb

Class Method Summary collapse

Instance Method Summary collapse

Methods included from Construct

#find

Class Method Details

.create(base_locator, params = {}) {|tm| ... } ⇒ Object

Yields:

  • (tm)


74
75
76
77
78
79
80
# File 'lib/rtm/activerecord/topic_map.rb', line 74

def self.create(base_locator, params={})
  bl_uri = URI.parse(base_locator)
  raise "The locator for the Topic Map must be absolute! \"#{base_locator}\" is not an absolute locator." unless bl_uri.absolute?
  tm = self.wrap(TMDM::TopicMap.find_or_create_by_base_locator(base_locator))
  yield tm if block_given?
  tm
end

.topic_mapsObject



82
83
84
# File 'lib/rtm/activerecord/topic_map.rb', line 82

def self.topic_maps
  TopicMaps.wrap(TMDM::TopicMap.find(:all))
end

Instance Method Details

#_by_item_identifier(iid) ⇒ Object

internal helper for by_item_identifier, doesn’t wrap result



141
142
143
144
145
146
# File 'lib/rtm/activerecord/topic_map.rb', line 141

def _by_item_identifier(iid)
  iid = RTM::LocatorHelpers.iid2iri(iid) if RTM::LocatorHelpers.is_a_iid?(iid)
  ii = __getobj__.locators.find_by_reference(resolve(iid.to_s.sub(/^(\^|ii:)\s*/,""))) #, :include => [ :construct ])
  return ii.construct if ii
  nil
end

#_item_identifier(iid) ⇒ Object

private



118
119
120
# File 'lib/rtm/activerecord/topic_map.rb', line 118

def _item_identifier(iid)
  __getobj__.locators.find_by_reference(resolve(iid)) # doesn't work :( --> , :include => [ :construct ])
end

#_item_identifier!(iid) ⇒ Object



121
122
123
# File 'lib/rtm/activerecord/topic_map.rb', line 121

def _item_identifier!(iid)
  __getobj__.locators.find_or_create_by_reference(resolve(iid)) # doesn't work :( --> , :include => [ :construct ])
end

#_subject_identifier(iid) ⇒ Object



125
126
127
# File 'lib/rtm/activerecord/topic_map.rb', line 125

def _subject_identifier(iid)
  __getobj__.subject_identifiers.find_by_reference(iid, :include => :topic)
end

#_subject_identifier!(iid) ⇒ Object



128
129
130
# File 'lib/rtm/activerecord/topic_map.rb', line 128

def _subject_identifier!(iid)
  __getobj__.subject_identifiers.find_or_create_by_reference(iid, :include => :topic)
end

#_subject_locator(iid) ⇒ Object



132
133
134
# File 'lib/rtm/activerecord/topic_map.rb', line 132

def _subject_locator(iid)
  __getobj__.subject_locators.find_by_reference(iid, :include => :topic)
end

#_subject_locator!(iid) ⇒ Object



135
136
137
# File 'lib/rtm/activerecord/topic_map.rb', line 135

def _subject_locator!(iid)
  __getobj__.subject_locators.find_or_create_by_reference(iid, :include => :topic)
end

#_topic_by_item_identifier(iid) ⇒ Object



147
148
149
150
151
152
# File 'lib/rtm/activerecord/topic_map.rb', line 147

def _topic_by_item_identifier(iid)
  t = _by_item_identifier(iid)
  return nil unless t
  return t if t.class.name =~ /::Topic$/ # only return something if the thing is a topic
  nil
end

#_topic_by_item_identifier!(iid) ⇒ Object

internal helper for topic_by_item_identifier!, doesn’t wrap result



155
156
157
158
159
160
161
162
163
164
165
166
167
# File 'lib/rtm/activerecord/topic_map.rb', line 155

def _topic_by_item_identifier!(iid)
  iid = RTM::LocatorHelpers.iid2iri(iid) if RTM::LocatorHelpers.is_a_iid?(iid)
  ii = __getobj__.locators.find_or_create_by_reference(resolve(iid.to_s.sub(/^(\^|ii:)\s*/,"")))#, :include => [ :construct ])
  return ii.construct if ii.construct && ii.construct_type =~ /::Topic$/
  top2 = _topic_by_subject_identifier(resolve(iid))
  if top2
    ii.construct = top2
  else
    ii.construct = create_topic.__getobj__
  end
  ii.save
  ii.construct
end

#_topic_by_locator(iri) ⇒ Object



208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
# File 'lib/rtm/activerecord/topic_map.rb', line 208

def _topic_by_locator(iri)
  raise "Locator may not be nil" unless iri
  return iri if iri.is_a?(RTM::AR::TMDM::Topic)
  return iri.__getobj__ if iri.is_a?(RTM::AR::Topic)
  if iri.is_a?(Array)
    return iri.map{|i| _topic_by_locator(i)}
  end
  if RTM::LocatorHelpers.is_a_slo?(iri)
    _topic_by_subject_locator(iri)
  elsif RTM::LocatorHelpers.is_a_iid?(iri)
    _topic_by_item_identifier(iri)
  #elsif URI.parse(iri).absolute?
  #  _topic_by_subject_identifier(iri)
  else
    _topic_by_subject_identifier(iri)
  end
end

#_topic_by_locator!(iri) ⇒ Object



226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
# File 'lib/rtm/activerecord/topic_map.rb', line 226

def _topic_by_locator!(iri)
  raise "Locator may not be nil" unless iri
  return iri if iri.is_a?(RTM::AR::TMDM::Topic)
  return iri.__getobj__ if iri.is_a?(RTM::AR::Topic)
  if iri.is_a?(Array)
    return iri.map{|i| _topic_by_locator!(i)}
  end
  if RTM::LocatorHelpers.is_a_slo?(iri)
    _topic_by_subject_locator!(iri)
  elsif RTM::LocatorHelpers.is_a_iid?(iri)
    _topic_by_item_identifier!(iri)
  #elsif RTM::LocatorHelpers.is_a_sid?(iri)
  #  _topic_by_subject_identifier!(iri)
  else
    _topic_by_subject_identifier!(iri)
  end
end

#_topic_by_subject_identifier(sid) ⇒ Object

internal helper for topic_by_subject_identifier, doesn’t wrap result



169
170
171
172
173
# File 'lib/rtm/activerecord/topic_map.rb', line 169

def _topic_by_subject_identifier(sid)
  si = __getobj__.subject_identifiers.find_by_reference(resolve(sid.to_s.sub(/^(si:)\s*/,"")), :include => [ :topic ])
  return si.topic if si
  nil
end

#_topic_by_subject_identifier!(sid) ⇒ Object

internal helper for topic_by_subject_identifier!, doesn’t wrap result



175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
# File 'lib/rtm/activerecord/topic_map.rb', line 175

def _topic_by_subject_identifier!(sid)
  si =  __getobj__.subject_identifiers.find_or_create_by_reference(resolve(sid.to_s.sub(/^(si:)\s*/,"")), :include => [ :topic ])
  return si.topic if si.topic
  begin
  top2 = _by_item_identifier(sid)
  rescue ActiveRecord::RecordNotFound => rnf
    si.topic = create_topic.__getobj__
  else
    if top2 && top2.respond_to?(:subject_identifiers)
      si.topic = top2
    else
      si.topic = create_topic.__getobj__
    end
  end
  si.save
  si.topic
end

#_topic_by_subject_locator(slo) ⇒ Object

internal helper for topic_by_subject_locator, doesn’t wrap result



194
195
196
197
198
# File 'lib/rtm/activerecord/topic_map.rb', line 194

def _topic_by_subject_locator(slo)
  sl = __getobj__.subject_locators.find_by_reference(resolve(RTM::LocatorHelpers.slo2iri(slo))) #, :include => [ :topic ])
  return sl.topic if sl
  nil
end

#_topic_by_subject_locator!(slo) ⇒ Object

internal helper for topic_by_subject_locator!, doesn’t wrap result



201
202
203
204
205
206
207
# File 'lib/rtm/activerecord/topic_map.rb', line 201

def _topic_by_subject_locator!(slo)
  sl = __getobj__.subject_locators.find_or_create_by_reference(resolve(RTM::LocatorHelpers.slo2iri(slo)), :include => [ :topic ])
  return sl.topic if sl.topic
  sl.topic = create_topic.__getobj__
  sl.save
  sl.topic
end

#by_item_identifier(iid) ⇒ Object Also known as: get_construct_by_item_identifier

Returns a topic map construct by it’s item identifier or nil if not found. It’s the equivalent to TMAPI’s TopicMapObjectIndex.getTopicMapObjectBySourceLocator



264
265
266
# File 'lib/rtm/activerecord/topic_map.rb', line 264

def by_item_identifier(iid)
  Construct.wrap(_by_item_identifier(iid))
end

#childrenObject



425
426
427
# File 'lib/rtm/activerecord/topic_map.rb', line 425

def children
  topics.to_a + associations.to_a
end

#closeObject



8
9
# File 'lib/rtm/activerecord/topic_map.rb', line 8

def close 
end

#create_association(type, scope = :default) ⇒ Object



19
20
21
22
23
24
25
26
27
28
29
# File 'lib/rtm/activerecord/topic_map.rb', line 19

def create_association(type, scope = :default)
  raise "type must be a Topic or Topic-Reference" unless type.is_a?(RTM::Topic) || type.is_a?(String) || type.is_a?(RTM::Locator)
  if scope.eql? :default
    return create_association_internal(get!(type))
  else
    raise "scope must be an Array" unless scope.is_a?(Array)
    a = create_association_internal(get!(type))
    scope.each {|s| a.add_scope(get!(s))}
    return a
  end
end

#create_topic_by(identifier) ⇒ Object

Assumes identifier is an IRI (Locator or String) or an Array of IRIs. Returns an existing or created Topic or an Array of Topics according to the nature of the IRI.

:call-seq:

create_topic_by(identifier) -> Topic
create_topic_by(identifier-Array) -> Array of Topics


354
355
356
357
358
359
360
361
362
363
364
365
# File 'lib/rtm/activerecord/topic_map.rb', line 354

def create_topic_by(identifier)
  case identifier
    when RTM::Locator
      return create_topic_by_subject_identifier(identifier)
    when String
      reroute_for_create(identifier)
    when Array
      return identifier.map{|i| create_topic_by(i)}
    else
      return nil
  end
end

#external_occurrencesObject



70
71
72
# File 'lib/rtm/activerecord/topic_map.rb', line 70

def external_occurrences
  occurrences.select{|o| o.datatype == RTM::PSI[:IRI]}
end

#fast_typesObject



46
47
48
# File 'lib/rtm/activerecord/topic_map.rb', line 46

def fast_types
  
end

#individualsObject

This fetches all topics which are not type for something else (including topics, associations etc.). See non_types



58
59
60
# File 'lib/rtm/activerecord/topic_map.rb', line 58

def individuals
  non_types.select{|t| t.associations_typed.size==0 && t.roles_typed.size==0 && t.names_typed.size==0 && t.occurrences_typed.size==0}
end

#instancesObject



61
62
63
# File 'lib/rtm/activerecord/topic_map.rb', line 61

def instances
  topics.select{|t| t.types.size > 0}
end

#internal_occurrencesObject



67
68
69
# File 'lib/rtm/activerecord/topic_map.rb', line 67

def internal_occurrences
  occurrences.select{|o| o.datatype != RTM::PSI[:IRI]}
end

#item_identifier(iid) ⇒ Object

returns an item identifier from the topic_map if it exists



253
254
255
# File 'lib/rtm/activerecord/topic_map.rb', line 253

def item_identifier(iid)
  ItemIdentifier.wrap(_item_identifier(iid))
end

#item_identifier!(iid) ⇒ Object Also known as: create_locator

returns an item identififier from the topic_map or creates it if it doesn’t exist



257
258
259
# File 'lib/rtm/activerecord/topic_map.rb', line 257

def item_identifier!(iid)
  ItemIdentifier.wrap(_item_identifier!(iid))
end

#literal_indexObject



429
430
431
# File 'lib/rtm/activerecord/topic_map.rb', line 429

def literal_index
  LiteralIndex.new(self)
end

#non_instancesObject



64
65
66
# File 'lib/rtm/activerecord/topic_map.rb', line 64

def non_instances
  topics.reject{|t| t.types.size > 0}
end

#non_typesObject

This fetches all topics who have no topic-instances (but they might be types for associations etc.). See indivduals



52
53
54
# File 'lib/rtm/activerecord/topic_map.rb', line 52

def non_types
  topics.select{|t| t.instances.size == 0}
end

#reroute_for_create(identifier) ⇒ Object

Identifies the identifier as item identifier, subject locator or subject identifier and calls create_topic_by_.. accordingly. Creates new topic if topic does not exist yet. Returns the topic.

:call-seq:

reroute_for_create(identifier) -> Topic


374
375
376
377
378
379
380
381
382
383
384
385
# File 'lib/rtm/activerecord/topic_map.rb', line 374

def reroute_for_create(identifier)
  case identifier
   when /^(\^|ii:)\s*(.*)/ #identifiers starts with ^ or ii:
     create_topic_by_item_identifier(create_locator($2))
   when /^(=|sl:)\s*(.*)/ #identifier starts with = or sl:
     create_topic_by_subject_locator(create_locator($2))
   when /^(si:)\s*(.*)/ #identifier starts with si:
     create_topic_by_subject_identifier(create_locator($2))
   else #identifier does not start with a special character
     create_topic_by_subject_identifier(create_locator(identifier.lstrip))#lstrip: leading whitespace chars removed
  end
end

#reroute_for_get(identifier) ⇒ Object

Identifies the identifier as item identifier, subject locator or subject identifier and calls get_construct/topic_by_.. accordingly. Returns the topic.

:call-seq:

reroute_for_get(identifier) -> Topic


394
395
396
397
398
399
400
401
402
403
404
405
406
407
# File 'lib/rtm/activerecord/topic_map.rb', line 394

def reroute_for_get(identifier)
  case identifier
    when /^(si:|sl:|ii:|=|^)$/
      return nil
    when /^(\^|ii:)\s*(.*)/ #identifiers starts with ^ or ii:
      get_construct_by_item_identifier(create_locator($2))
    when /^(=|sl:)\s*(.+)/ #identifier starts with = or sl:
      get_topic_by_subject_locator(create_locator($2))
    when /^(si:)\s*(.+)/ #identifier starts with si:
      get_topic_by_subject_identifier(create_locator($2))
  else #identifier does not start with a special character
    get_topic_by_subject_identifier(create_locator(identifier.lstrip)) #lstrip: leading whitespace chars removed
  end
end

#resolve(obj, alternative_base_locator = nil) ⇒ Object

Resolves an IRI or fragment relative to the base_locator of this topic_map or an optional given alternative_base_locator

Absolute IRIs are taken as is.

Relative IRIs: If the base_locator is a directory (ends with “/”) it is appended like a file, i.e. directly If the base_locator is a file it is appended as a fragment (with # in between)



93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
# File 'lib/rtm/activerecord/topic_map.rb', line 93

def resolve(obj,alternative_base_locator=nil)
  uri = obj.to_s
# TODO     uri = URI.decode(obj.to_s) # this InvalidURIError somethimes :(
  begin
    uri_uri = URI.parse(uri)
  rescue URI::InvalidComponentError => ice
    warn "Catched an URI::InvalidComponentError for URI: #{uri}, message was \"#{ice.message}\"\n" +
      "Will continue using the UNRESOLVED IRI, claiming it is absolute."
    return uri
  end
  if uri_uri.absolute?
    return uri_uri.to_s
  end
  
  uri = uri[1..-1] if uri[0] == "#"[0]
  bl = alternative_base_locator || base_locator
  if bl[-1,1] == "/"
    return bl + uri
  else
    return bl + "#" + uri
  end
end

#topic_by_item_identifier!(iid) ⇒ Object Also known as: create_topic_by_item_identifier

Returns a topic by it’s item identifier. The topic will be created if not found.



270
271
272
# File 'lib/rtm/activerecord/topic_map.rb', line 270

def topic_by_item_identifier!(iid)
  Topic.wrap(_topic_by_item_identifier!(iid))
end

#topic_by_locator(iri) ⇒ Object Also known as: get

Gets a topic from this topic map using its (relative) item identifier, its (absolute) subject identifier or its (absolute and by “=” prepended) subject locator)

Returns nil if the Topic does not exist.

It’s also possible to pass a number, which is used to fetch a topic using the internal id. In this case, an exception is thrown, if the topic does not exist.



308
309
310
311
312
313
314
315
316
317
318
319
320
321
# File 'lib/rtm/activerecord/topic_map.rb', line 308

def topic_by_locator(iri)
  return nil unless iri
  return iri if iri.is_a? Topic
  return topic_by_id(iri) if iri.is_a? Integer
  if iri.is_a?(Array)
    return iri.map{|i| topic_by_locator(i)}
  end
#      @tblc ||= {}
#      t = @tblc[iri]
#      return t if t
  Topic.wrap(_topic_by_locator(iri)) # t = ...
#      @tblc[iri] = t if t
#      t
end

#topic_by_locator!(iri) ⇒ Object Also known as: get!

Gets a topic from this topic map using its (relative) item identifier, its (absolute) subject identifier or its (absolute and by “=” prepended) subject locator)

If there is no topic with this item identifier, subject identifier or subject locator, it is created. Please be aware, the creation does not work with the internal (numeric) ids.



330
331
332
333
334
335
336
337
338
339
340
341
342
343
# File 'lib/rtm/activerecord/topic_map.rb', line 330

def topic_by_locator!(iri)
  return nil unless iri
  return iri if iri.is_a? Topic
  return topic_by_id(iri) if iri.is_a? Integer
  if iri.is_a?(Array)
    return iri.map{|i| topic_by_locator!(i)}
  end
#      @tblc ||= {}
#      t = @tblc[iri]
#      return t if t
  Topic.wrap(_topic_by_locator!(iri)) # t = ...
#      @tblc[iri] = t
#      t
end

#topic_by_subject_identifier(sid) ⇒ Object Also known as: get_topic_by_subject_identifier

Returns a topic by it’s subject identifier or nil if not found. It’s the equivalent to TMAPI’s TopicsIndex.getTopicBySubjectIdentifier.



277
278
279
# File 'lib/rtm/activerecord/topic_map.rb', line 277

def topic_by_subject_identifier(sid)
  Topic.wrap(_topic_by_subject_identifier(sid))
end

#topic_by_subject_identifier!(sid) ⇒ Object Also known as: create_topic_by_subject_identifier

returns a topic by it’s subject identifier. The topic will be created if not found.



283
284
285
# File 'lib/rtm/activerecord/topic_map.rb', line 283

def topic_by_subject_identifier!(sid)
  Topic.wrap(_topic_by_subject_identifier!(sid))
end

#topic_by_subject_locator(slo) ⇒ Object Also known as: get_topic_by_subject_locator

Returns a topic by it’s subject locator or nil if not found. It’s the equivalent to TMAPI’s TopicsIndex.getTopicBySubjectLocator



290
291
292
# File 'lib/rtm/activerecord/topic_map.rb', line 290

def topic_by_subject_locator(slo)
  Topic.wrap(_topic_by_subject_locator(slo))
end

#topic_by_subject_locator!(slo) ⇒ Object Also known as: create_topic_by_subject_locator

returns a topic by it’s subject locator. The topic will be created if not found.



296
297
298
# File 'lib/rtm/activerecord/topic_map.rb', line 296

def topic_by_subject_locator!(slo)
  Topic.wrap(_topic_by_subject_locator!(slo))
end

#typesObject Also known as: topic_types



42
43
44
# File 'lib/rtm/activerecord/topic_map.rb', line 42

def types
  topics.select{|t| t.instances.size > 0}
end