# Copyright: Copyright 2009 Topic Maps Lab, University of Leipzig. # License: Apache License, Version 2.0 module RTM::Sugar::Role module Counterparts # Returns all roles from the parent association of this role, # except itself. # # A filter-hash may be used to filter for the type of the other roles # (:otype) or the player of the other roles (:oplayer). # # The identfiers may be topic references. # # :call-seq: # counterparts -> Array of Roles # counterparts({:otype => identifier}) -> Array of Roles # def counterparts(filter={}) _roles = parent.roles.reject{|r| r.id==self.id} otype = filter[:otype] _roles = _roles.select{|r| r.type == topic_map.get(otype)} if otype && otype != :any oplayer = filter[:oplayer] _roles = _roles.select{|r| r.player == topic_map.get(oplayer)} if oplayer && oplayer != :any return _roles end # Returns the other role, if the parent association is binary. # # :call-seq: # counterpart -> Role # def counterpart n = parent.roles.size raise "Association must be unary or binary to use counterpart method. Please use counterparts for n-ary associations." if n > 2 return nil if n == 1 counterparts.first end # Returns all players of the parent Association of this Role, # except the player of itself. # # A filter-hash may be used to filter for the type of the other Roles # (:otype). The identifier may be a topic reference. # # :call-seq: # counterplayers -> Array of Topics # counterplayers({:otype => identifier}) -> Array of Topics # def counterplayers(filter={}) counterparts(filter).map{|r| r.player} end # Returns the player of the other role, if the parent association is binary. # # :call-seq: # counterplayer -> Topic # def counterplayer n = parent.roles.size raise "Association must be unary or binary to use counterplayer method. Please use counterplayers for n-ary associations (n>2)." if n > 2 return nil if n == 1 counterparts.first.player end # Returns the Roles of other binary Associations for which the following # applies: # # - this Role and all returned Roles must share a counterplayer. # # - if :rtype is set to :strict, the type of the returned Roles must equal # the type of this Role # # - if :atype is set to :strict, the type of the parent Associaton of this Role must be equal # to the type of the parent Associations of the other Roles # # - if :otype is set to :strict, the type of the Roles the shared counterplayers play (counterparts) # must equal # # - if :arity is set to :strict, the size of the parent Associations must # equal the size of the other associations involved # # Example: Returns all employee-roles of a company, if self is a Role an employee plays in an # "firm-employee"-Association. # # Default: peers(:arity => :strict, :atype => :strict, :otype => :strict, :rtype => :strict) # # The result may be empty. Esp. if the parent Association includes only this Role, an empty Array is returned. # # :call-seq: # peers -> Array of Roles # peers(:arity => :strict) -> Array of Roles # peers(:rtype => :strict, :atype => strict, :otype => :loose) -> Array of Roles # etc. # def peers(params = {}) default_hash = {:arity => :strict, :atype => :strict, :otype => :strict, :rtype => :strict} raise("peers: argument has to be a Hash") unless params.is_a? Hash params.reject!{|k,v| ![:strict,:loose].include?(v)} params = default_hash.merge(params) # puts "\narity = " + (params[:arity] == :strict ? "strict" : "loose") # puts "atype = " + (params[:atype] == :strict ? "strict" : "loose") # puts "otype = " + (params[:otype] == :strict ? "strict" : "loose") # puts "rtype = " + (params[:rtype] == :strict ? "strict" : "loose") n = self.parent.roles.size return [] if n == 1 atype = self.parent.type # association type rtype = self.type #role type c_parts = self.counterparts # other roles in the association of this player _roles = [] c_parts.each do |c_part| otype = c_part.type # type of the other role in the association c_player = c_part.player if params[:otype] == :loose other_roles = c_player.roles.to_a else if params[:atype] == :strict other_roles = c_player.roles(otype,atype).to_a else other_roles = c_player.roles(otype).to_a end end other_roles = other_roles.select{|r| r.parent.roles.size == n} if params[:arity] == :strict #same n-ary other_roles = other_roles.map{|r| r.counterparts}.flatten # other roles in these associations other_roles = other_roles.select{|r| r.type == rtype} if params[:rtype] == :strict other_roles = other_roles.reject{|r| r == self} # reject self _roles = _roles + other_roles end return _roles end # Returns all players of the peers of this Role. # # Example: Returns all employees of a company except the # player of itself. # # :call-seq: # peerplayers -> Array of Topics # def peerplayers peers.map{|r| r.player} end end end