#:include: ../shared/license.rdoc #require "ontomde-core/exceptions.rb" require "singleton" # Helper methods to handle rdf ressources as object. module IteratorOrSingleElement def to_s r="" sep="" self.each{ |elt| r=r+sep+(elt.to_s) sep=" " } return r end def isFalse? return !isTrue? end def +(array) return self if array.kind_of?(ArrayOrSingleElementEmpty) return super(array) end STRING_TO_BOOLEAN_HASH={ "false" => false, "true" => true} def other_implem_isTrue? return false if length==0 raise Warning.new,"bad data for isTrue?(length=#{length}>1)" if length>1 ret=STRING_TO_BOOLEAN_HASH[self[0]] return ret unless ret.nil? raise Warning.new,"bad data for isTrue?(#{self[0]})" if length>1 end def isTrue? #return false if length==0 return false if empty? raise Warning.new,"bad data for isTrue?(length=#{length}>1)" if length>1 return false if self[0]=="false" return true if self[0]=="true" raise Warning.new,"bad data for isTrue?(#{self[0]})" if length>1 end end class ArrayOrSingleElement < Array include IteratorOrSingleElement end class SetOrSingleElement < Set include IteratorOrSingleElement end # Singleton of an empty ArrayOrSingleElement # Note: # This object is used for performance enhancement. class ArrayOrSingleElementEmpty #< ArrayOrSingleElement include Singleton # Size of an empty Array (always 0) def size 0 end # Size of an empty Array (always 0) def length 0 end # Iterator (does nothing) def each end # returns self as def select # quelque-soit le critere # de selection le retour est tout aussi vide return self; end # returns array def +(array) return array end # returns !isTrue? def isFalse? return !isTrue? end # returns false def isTrue? return false end # returns "" def to_s return "" end #return true def empty? return true end #returns false def include?(elt) return false end def delete(elt) return nil end def sort(&block) return self end end module Kernel #Creates accessors for rdf property passed as argument. # #Example: # for rdf_safe_attr_reader_many uml_abcde_efgh # the following methods are generated # # def uml_abcd_efgh () # returns an Array of reference elements. # (This array is READ-ONLY) # # def uml_efgh () # same as uml_abcd_efgh # in case of name clashing use long version. # # def uml_efgh_one() # Returns nil if array is empty # Triggers an error if array contains more than one element. # returns the first element of array # # def uml_efgh=(x) # reset array and add x # # def uml_efgh_add(x) # add x to the existing array # # def uml_efgh? # returns uml_efgh.isTrue?() # def rdf_safe_attr_reader_many(*syms) #attr_reader(*args) # TODO: ne pas crer un objet vide systématiquement. syms.each do |sym| #sym_array=sym.to_s.split("_",3) #sym_short="" #if sym_array[0]=="uml" && sym_array[2]!="" # sym_short="#{sym_array[0]}_#{sym_array[2]}" #else sym_short=sym #end #version normale #TODO: supprimer la version normale # ou raccourcir les nom en amont #class_eval %{def #{sym} # log.warn "method #{sym} is deprecated. Use #{sym_short} instead" # @#{sym}.nil? ? ::ArrayOrSingleElementEmpty.instance : @#{sym} #end} #version courte #log.debug "sym_short: >#{sym_array[0]}< >#{sym_array[1]}< >#{sym_array[2]}<" #log.debug sym_short class_eval %{def #{sym_short} @#{sym}.nil? ? ::ArrayOrSingleElementEmpty.instance : @#{sym} end} Crdf_Resource.class_eval %{def #{sym_short}_inv ret=nil ext_isReferencedBy.each { |g| next unless g.respond_to?(:#{sym_short}) next unless g.#{sym_short}.include?(self) ret=::ArrayOrSingleElement.new if ret.nil? next if ret.include?(g) ret << g } ret.nil? ? ::ArrayOrSingleElementEmpty.instance : ret end} Crdf_Resource.class_eval %{def #{sym_short}_inv_one(warn=true) i=#{sym_short}_inv if i.nil? || i.size==0 log_error_nil_one("#{sym_short}_inv") if warn return nil end return i[0] if i.length==1 log.error "#{sym_short}_inv_one used with multi-value (class=\#{self.class.name})(uri=\#{rdf_uri})(length=\#{@#{sym}.length})(value=(\#{@#{sym}.to_s}) Returning first one found as workaround : (\#{@#{sym}[0]})" return i[0] end} class_eval %{def #{sym_short}? return #{sym_short}.isTrue? end} class_eval %{def #{sym_short}_one(warn=true) if @#{sym}.nil? || @#{sym}.size==0 log_error_nil_one("#{sym_short}") if warn return nil end return @#{sym}[0] if @#{sym}.length==1 #log.error Warning.new,"#{sym_short}_one used with multi-value (class=\#{self.class.name})(uri=\#{rdf_uri})(length=\#{@#{sym}.length})(value=(\#{@#{sym}.to_s})" log.error "#{sym_short}_one used with multi-value (class=\#{self.class.name})(uri=\#{rdf_uri})(length=\#{@#{sym}.length})(value=(\#{@#{sym}.to_s}) Returning first one found as workaround : (\#{@#{sym}[0]})" return @#{sym}[0] end} class_eval %{def #{sym_short}_one0() #{sym_short}_one(false) end} inv=(sym_short.to_s=="ext_isReferencedBy") ? "" : "item.ext_isReferencedBy_add(self) if item.respond_to?(:ext_isReferencedBy_add) " #puts "sym_short=#{sym_short} #{inv}" #puts "adding method def #{sym_short}=(v) for #{self.name}" class_eval %{def #{sym_short}=(v) if v.nil? @#{sym}=nil elsif v.kind_of?(ArrayOrSingleElement) || v.kind_of?(Array) || v.kind_of?(ArrayOrSingleElementEmpty) @#{sym}= ArrayOrSingleElement.new v.each { |item| @#{sym}.push(item) #{inv} } else @#{sym}= ArrayOrSingleElement.new @#{sym}.push(v) item=v #{inv} end end} class_eval %{def #{sym_short}_add(item) if !item.nil? #log.debug @#{sym}.size+1000 if @#{sym}.nil? #log.debug "reset @#{sym}" @#{sym}= ArrayOrSingleElement.new end @#{sym}.push(item) #{inv} end end} end end end module Mrdf_Model def mtk_object_message return "" end def mtk_related_message return "" end end module Mrdf_Resource #return a string describing this object #(used for error log messages) def mtk_object_message return <