# Copyright: Copyright 2009 Topic Maps Lab, University of Leipzig. # License: Apache License, Version 2.0 module Java::OrgTmapiCore::Topic include RTM::Topic extend Superiseable # Returns all Names and Occurrences parented by this Topic. # # :call-seq: # children -> Array of Names and/or Occurrences # def children getNames.to_a + getOccurrences.to_a end alias :reverse_parent :children superised # Returns Names of this Topic. # # If identifier is given, returns the Names # of this Topic for which the Name type equals identifier. # If several identifiers are given, returns the union # of all Names of this Topic, which have one of # the identifiers as Name type. # # If the identifier equals :default, all Names # which have the default Name type are returned. # # Identifier may be a topic reference or Symbol; # or an Array of these. # # :call-seq: # names -> Set of Names # names(identifier) -> Set of Names # def names(*args) identifier = args.flatten return getNames if identifier.empty? if identifier.size > 1 result = java.util.HashSet.new identifier.each{|i| result.addAll(names(i))} return result else identifier = identifier[0] return getNames if identifier == :any return getNames(topic_map.get(RTM::PSI[:name_type])) if identifier == :default identifier = topic_map.get(identifier) return java.util.HashSet.new unless identifier return getNames(identifier) end end superised # Returns Occurrences of this Topic. # # If identifier is given, returns the Occurrences # of this Topic for which the Occurrence type equals identifier. # If several identifiers are given, returns the union # of all Occurrences of this Topic, which have one of # the identifiers as Occurrence type. # # Identifier may be a topic reference or an Array of these. # # :call-seq: # occurrences -> Set of Occurrences # occurrences(identifier) -> Set of Occurrences # def occurrences(*args) identifier = args.flatten return getOccurrences if identifier.empty? if identifier.size > 1 result = java.util.HashSet.new identifier.each{|i| result.addAll(occurrences(i))} return result else identifier = identifier[0] return getOccurrences if identifier == :any identifier = topic_map.get(identifier) return java.util.HashSet.new unless identifier return getOccurrences(identifier) end end superised # Creates a Name for this Topic with the specified value. # Value has to be a String. # # Type may be a topic reference. # If given, type specifies the Name Type; # else the created Name will have the default name type. # # Scope must be an Array of Topics/Topic-References. # If given, scope specifies the Name scope; else the Name is # in the unconstrained scope. # # :call-seq: # create_name(value) -> Name # create_name(value, scope) -> Name # create_name(type, value) -> Name # create_name(type, value, scope) -> Name # def create_name(arg1,arg2 = :nothing, arg3 = :nothing) if (arg2 == :nothing) && (arg3 == :nothing) #arg1 = value raise "create_name(value): value must be a String" unless arg1.is_a?(String) return createName(arg1,new_empty_java_topic_array) end if (arg3 == :nothing) if arg2.is_a?(Array) #arg1 = value, arg2 = scope raise "create_name(value, scope): value must be a String" unless arg1.is_a?(String) arg2.each do |theme| raise "create_name(value, scope): scope must be an Array of Topics/Topic-References" unless (theme.is_a?(String) || theme.is_a?(Java::OrgTmapiCore::Topic) || theme.is_a?(Java::OrgTmapiCore::Locator)) end return arg2.empty? ? createName(arg1,new_empty_java_topic_array) : createName(arg1,topic_map.get!(arg2)) elsif arg2.is_a?(String) #arg1 = type, arg2 = value raise "create_name(type, value): type must be a Topic/Topic-Reference" unless (arg1.is_a?(String) || arg1.is_a?(Java::OrgTmapiCore::Topic) || arg1.is_a?(Java::OrgTmapiCore::Locator)) return createName(topic_map.get!(arg1),arg2,new_empty_java_topic_array) else raise "create_name(?,?): arguments don't match" end end #arg1 = type, arg2 = value, arg3 = scope raise "create_name(type, value, scope): type must be a Topic/Topic-Reference" unless (arg1.is_a?(String) || arg1.is_a?(Java::OrgTmapiCore::Topic) || arg1.is_a?(Java::OrgTmapiCore::Locator)) raise "create_name(type, value, scope): value must be a String" unless arg2.is_a?(String) raise "create_name(type, value, scope): scope must be an Array" unless arg3.is_a?(Array) arg3.each do |theme| raise "create_name(type, value, scope): scope must be an Array of Topics/Topic-References" unless (theme.is_a?(String) || theme.is_a?(Java::OrgTmapiCore::Topic) || theme.is_a?(Java::OrgTmapiCore::Locator)) end return createName(topic_map.get!(arg1),arg2,topic_map.get!(arg3)) end superised # Creates an Occurrence for this Topic with the specified type and value and # optional scope and datatype. # # Type specifies the Occurrence type and may be a topic reference. # # Value may be a Locator (then the datatype is set to xsd:AnyURI and # must not be given) or String. # # Scope may be an Array of topic reference. If no scope # is given, the Occurrence will be in the unconstrained scope. # # Datatype may be a String or Locator and indicates the datatype of the value. # # :call-seq: # create_occurrence(type, value) -> Occurrence # create_occurrence(type, value, {:scope => scope}) -> Occurrence # create_occurrence(type, value, {:datatype => datatype, :scope => scope}) -> Occurrence # create_occurrence(type, value, {:datatype => datatype}) -> Occurrence # def create_occurrence(type,value,params={}) # creating a topic for the type type = topic_map.get!(type) # reading the datatype if given. nil otherwise datatype = params[:datatype] # reading value and setting datatype if not done before unless datatype if value.is_a?(Java::OrgTmapiCore::Locator) datatype = RTM::PSI[:IRI] elsif value.is_a?(String) datatype = RTM::PSI[:String] elsif value.is_a?(Float) datatype = RTM::PSI[:Float] elsif value.is_a?(Fixnum) datatype = RTM::PSI[:Long] elsif value.is_a?(Bignum) datatype = RTM::PSI[:Integer] elsif value.is_a?(DateTime) #DateTime is a Time and a Date datatype ||= RTM::PSI[:DateTime] elsif value.is_a?(Time) datatype ||= RTM::PSI[:Time] elsif value.is_a?(Date) datatype ||= RTM::PSI[:Date] else raise NoDatatypeHandlerAvailableException.new(value) end end # creating locator for datatype datatype = topic_map.create_locator(datatype) # value must be a String value = value.to_s # if datatype is xsd:anyURI -> resolve value against base_iri if datatype.reference == RTM::PSI[:IRI] value = topic_map.create_locator(value).reference end begin if params[:scope] raise("scope must be an Array") unless params[:scope].is_a?(Array) return createOccurrence(type, value, datatype, topic_map.get!(params[:scope])) else #no scope return createOccurrence(type, value, datatype, new_empty_java_topic_array) end rescue java.lang.IllegalArgumentException => iae raise(iae.message) end end # Returns the TopicMap the Topic belongs to. # # :call-seq: # parent -> TopicMap # def parent getParent end alias :reverse_children :parent superised # Returns the Roles played by this Topic. # # If given, rtype specifies the type of the Roles to be returned; # If given, atype specifies the type of the Association # from which the returned Roles must be part of. # # rtype and atype may be a topic reference or Arrays of these types. # # The result may be empty. # # :call-seq: # roles -> Array of Roles # roles(rtype) -> Array of Roles # roles(rtype, atype) -> Array of Roles # def roles_played(rtype=:any, atype=:any) if rtype == :any # -> atype may only be :any if atype == :any return getRolesPlayed else raise "Associationtype may only be specified if rtype are specified" end end # Assume, that rtype is given or set to nil # atype may be :any rtype = topic_map.get(rtype) return Array.new if rtype == nil || (rtype.is_a?(Array) && rtype.include?(nil)) #Assume that rtype is given and found unless atype == :any atype = topic_map.get(atype) return Array.new if atype == nil || (atype.is_a?(Array) && atype.include?(nil)) end #Assume that if atype is given, it's found if rtype.is_a?(Array) #several rtype if atype == :any #no atype return rtype.map{|r| roles_played(r)}.inject(java.util.HashSet.new){|union,element| union.addAll(element); union} elsif atype.is_a?(Array) #several atype return rtype.map{|r| roles_played(r,atype)}.inject(java.util.HashSet.new){|union,element| union.addAll(element); union} else #one associationtype return rtype.map{|r| roles_played(r,atype)}.inject(java.util.HashSet.new){|union,element| union.addAll(element); union} end else #one roletype if atype == :any #no atype return getRolesPlayed(rtype) elsif atype.is_a?(Array) #several atype return atype.map{|a| roles_played(rtype,a)}.inject(java.util.HashSet.new){|union,element| union.addAll(element); union} else #one associationtype return getRolesPlayed(rtype,atype) end end end alias :roles :roles_played # Returns the subject identifiers assigned to the current topic. # # :call-seq: # subject_identifiers -> Set of Locators # def subject_identifiers getSubjectIdentifiers end superised # Adds a subject identifier to the current Topic. # Identifier may be a String or Locator. # # :call-seq: # add_subject_identifier(identifier) # def add_subject_identifier(identifier) begin if identifier.is_a? Java::OrgTmapiCore::Locator addSubjectIdentifier(identifier) else addSubjectIdentifier(topic_map.create_locator(identifier)) end rescue Java::OrgTmapiCore::IdentityConstraintException => ice # TODO add condition to switch off automerge self.mergeIn(self.topic_map.get(identifier)) end end superised # Removes a subject identifier from the this Topic, # if present. # # Identifier may be a String or Locator. # # :call-seq: # remove_subject_identifier(identifier) # def remove_subject_identifier(identifier) identifier = topic_map.create_locator(identifier) if identifier.is_a? String removeSubjectIdentifier(identifier) if identifier.is_a? Java::OrgTmapiCore::Locator end # Returns the subject locators assigned to the current topic. # # :call-seq: # subject_locators -> Set of Locators # def subject_locators getSubjectLocators end superised # Adds a subject locator to the current topic. # Identifier may be a String or Locator. # # :call-seq: # add_subject_locator(identifier) # def add_subject_locator(identifier) # TODO Spec begin if identifier.is_a? Java::OrgTmapiCore::Locator addSubjectLocator(identifier) else addSubjectLocator(topic_map.create_locator(identifier)) end rescue Java::OrgTmapiCore::IdentityConstraintException => ice # TODO add condition to switch off automerge self.mergeIn(self.topic_map.topic_by_subject_locator(identifier)) end end superised # Removes a subject locator from the this Topic, # if present. # # Identifier may be a String or Locator. # # :call-seq: # remove_subject_locator(identifier) # def remove_subject_locator(identifier) identifier = topic_map.create_locator(identifier) if identifier.is_a? String removeSubjectLocator(identifier) if identifier.is_a? Java::OrgTmapiCore::Locator end # superised # # Removes an item identifer from the this Topic, # # if present. # # # # Identifier may be a String or Locator. # # # # :call-seq: # # remove_item_identifier(identifier) # # # def remove_item_identifier(identifier) # identifier = topic_map.create_locator(identifier) if identifier.is_a? String # removeItemIdentifier(identifier) if identifier.is_a? Java::OrgTmapiCore::Locator # end superised # Adds a type given by the identifier to this Topic. # # Identifier may be a topic reference. # # :call-seq: # add_type(identifier) # def add_type(identifier) if identifier.is_a?(Java::OrgTmapiCore::Topic) addType(identifier) elsif identifier.is_a?(Java::OrgTmapiCore::Locator) || identifier.is_a?(String) addType(topic_map.get!(identifier)) else raise("Identifier must be a Topic, String or Locator") end end # Adds one or several types given by the identifiers. # # Identifier may be a topic reference. # # :call-seq: # add_types(identifier1, identifier2, ...) # def add_types(*args) args.flatten! args.each do |identifier| add_type(identifier) end end # Adds an instance given by the identifier to this Topic. # # Identifier may be a topic reference. # # :call-seq: # add_instance(identifier) # def add_instance(identifier) if identifier.is_a?(Java::OrgTmapiCore::Topic) identifier.addType(self) elsif identifier.is_a?(Java::OrgTmapiCore::Locator) || identifier.is_a?(String) topic_map.get!(identifier).addType(self) else raise("Identifier must be a Topic, String or Locator") end end # Adds one or several instances given by the identifiers. # # Identifier may be a topic reference. # # :call-seq: # add_instances(identifier1, identifier2, ...) # def add_instances(*args) args.flatten! args.each do |identifier| add_instance(identifier) end end # Returns the reifiable Construct which is reified by this Topic # or nil if this Topic does not reify a statement. # # :call-seq: # reifier -> Name, Occurrence, Variant, Association, Role or TopicMap # def reified getReified end # Sets this Topic as reifier of the reifiable Construct, given by the # identifier. # # Identifier may be a Name, Variant, Occurrence, Association, Role or # TopicMap. # # :call-seq: # reified = identifier # def reified=(identifier) if identifier.is_a?(Java::OrgTmapiCore::Reifiable) identifier.reifier = self return end raise("reified=: Identifier may be a Name, Variant, Occurrence, Association, Role or TopicMap") end superised # Removes a type given by the identifier of this topic, # if present. # # Identifier may be a topic reference. # # :call-seq: # remove_type(identifier) # def remove_type(identifier) if identifier.is_a? Java::OrgTmapiCore::Topic removeType(identifier) else identifier = topic_map.get(identifier) removeType(identifier) if identifier end end # Removes an instance given by the identifier of this topic, # if present. # # Identifier may be a topic reference. # # :call-seq: # remove_instance(identifier) # def remove_instance(identifier) identifier = topic_map.get(identifier) return unless identifier identifier.removeType(self) end # TODO extend this, maybe allow for a removal of any topic no matter how important # it may be for the whole topic map def force_remove self.roles_played.to_a.clone.each{|p| p.parent.remove} self.remove end private def new_empty_java_topic_array [].to_java(Java::OrgTmapiCore::Topic) end class NoDatatypeHandlerAvailableException < Exception def initialize(value) super "Cannot map #{value} to an occurrence value+datatype. Maybe you need to add a handler for your Ruby object type." end end end