require 'configatron' class Tripleizer def initialize output=nil @object_properties = configatron.objectProperties.to_hash @object_namespaches = configatron.namespaces.to_hash @class_map = configatron.classMap.to_hash @output=output @version="0.0.1" end attr_accessor :output attr_reader :version def tripleize (tr_self,c =nil,id=nil) #$this->writeTriple($self,$this->uri('rdfs:comment'),'Generated by Triplify '.$this->version.' (http://Triplify.org)',true); #if($this->config['license']) # $this->writeTriple($self,'http://creativecommons.org/ns#license',$this->config['license']); # configatron.queries.to_hash.each do |_class,q| # puts k.to_s+ " \n" # cols,group=nil,nil # # #TODO:mehrere Unterabfragen # # case configatron.LinkedDataDepth # when 3 # if !id # return #datentiefe von 3 gibts laut config nicht TODO:abfangen # end # when 2 # if !c # write_triple uri(_class),uri('rdf:type'), uri('owl:Class') # end # #TODO continue 2 # return # when 1 # # else # #TODO:DataDepthERROR # end # #TODO:some magic sql-query building # # #query sql # #for each result make_triples # # end end def search_models key model_groups = eval("configatron.query").to_hash model_groups.each do |model_group_name,model_group| if model_group_name.to_s.downcase == key.downcase return model_group end end end # def write_model model_name,model_attributes, output puts model_name if model_name.to_s == "OptionValue" hello = "Product" end model = Model.new(model_name) #dtypes =dbd_types model,model.model_attributes # data_types= model.get_datatypes #build hash model.get_rows.each do |item| line = Hash.new subline = Hash.new #and now add all mapping-attributes model.model_attributes.each do |k,v| if k.to_s.include?("->") #find all subelements submodel = eval("item."+v.downcase) if submodel.class != (Array) if submodel sub_m = Model.new(submodel.class.to_s) subline[:id] = item.id subline[k] = eval("submodel."+sub_m.get_key.to_s) #subline[k.split"->"[0]] = eval("item."+k.split"->"[1]+".id") sub_data_types = model.get_datatypes extract_id_line(model.model_attributes, subline, item, sub_data_types) output.write make_triples(subline, model.model_name , "", sub_data_types,false) end else unless submodel.empty? sub_m = Model.new(submodel[0].class.to_s) submodel.each do |submodel_item| subline[:id] = item.id subline[k] = eval("submodel_item."+sub_m.get_key.to_s) #subline[k.split"->"[0]] = eval("item."+k.split"->"[1]+".id") sub_data_types = model.get_datatypes extract_id_line(model.model_attributes, subline, item,sub_data_types) output.write make_triples(subline, model.model_name , "", sub_data_types,false) end end end else write_line = true; if v.to_s.include? "." write_line = nil unless eval("item."+v.to_s.split(".")[0]) end line[k.to_s]=eval("item."+v.to_s) if write_line end end extract_id_line(model.model_attributes, line, item,data_types) #watch if there is a mapping to another object with "->" #get triples of row output.write make_triples(line, model.model_name , "", data_types) #render :text => t.make_triples(c1, controller , "", t.dbd_types) end end def extract_id_line model_attributes, line,item,dtypes #look if id is mapped to another field id_keys = model_attributes.to_hash.keys #hotfix..bad performance id_keys.map!{|k| k.to_s } id_key= id_keys.select{|k| k =~/^(ID|id|iD|Id)$/ } if id_key.empty? line[:id] = item.id else line[:id] = eval("item.#{model_attributes[id_key[0].to_sym]}") #set the correct datatype for it dtypes["id"]= dtypes[id_key[0]] #remove the id line line.delete id_key[0] end end def write_sql model_name, model_attributes,output model_attributes.each do|key,query| sql= ActiveRecord::Base.connection(); (sql.select_all query).each do |row| output.write make_triples(row,model_name,"") end end end def write_rdf_head output # $this->writeTriple($self,$this->uri('rdfs:comment'),'Generated by Triplify '.$this->version.' (http://Triplify.org)',true); output.write write_triple($base_uri, uri("rdfs:comment"), 'Generated by Triplify '+'version'+ " (http://Triplify.org) ", "literal") unless configatron.license.blank? #$this->writeTriple($self,'http://creativecommons.org/ns#license',$this->config['license']); output.write write_triple($base_uri,'http://creativecommons.org/ns#license',configatron.license) end end def make_triples (c1,rdf_class,maketype,dtypes=Array.new,rdf_type=true) rdf_ns="http://www.w3.org/1999/02/22-rdf-syntax-ns#" ipref= uri rdf_class.to_s+'/' is_literal=false dtype,lang,ret="","","" object_property = nil unless c1[:id] id_row = c1.select {|k,v| k =~ /^(id|ID|iD|Id)$/} c1[:id] = id_row[0][1] c1.delete id_row[0][0] #set datatype for id #dtypes[:id] = uri( (id_row[0][1]).type) end subject = uri c1[:id].to_s,ipref #write model :-) c= @class_map[rdf_class.to_sym] ?@class_map[rdf_class.to_sym]:rdf_class ret+= write_triple subject, rdf_ns+"type", uri(c, @object_namespaches[:vocabulary]) if rdf_type c1.delete :id unless rdf_type c1.each do |k,v| k=k.to_s if v.to_s.empty? next end # beinhaltet key ^^ dann type oder sprache richtig setzen if k.index("^^") #TODO: k,dtype = k.split("^^") dtype= uri k.split("^^")[1] k= k.split("^^")[0] else if dtypes.include? k dtype= uri dtypes[k] else if k.index("@") lang=k.split("@")[1] k = k.split("@")[0] end end end # beinhaltet key -> dann muss objekt richtig gesetzt werden if k.index("->") k, object_property = k.split("->") else object_property = @object_properties[k] end #TODO #callbackfunktion # prop= self.uri(k,@object_namespaches[:vocabulary]) unless object_property is_literal= true object= v.to_s else is_literal= false #uri($objectProperty.($objectProperty&&substr($objectProperty,-1,1)!='/'?'/':'').$val); #TODO: fixme "/" in the middle #object= uri "#{object_property}/#{object_property && object_property[-1,1].to_s !="/" ?"/":":"}#{v}" object= uri "#{object_property}#{object_property[-1,1].to_s !="/" ? "/":":"}#{v}" end ret +=write_triple(subject,prop,object,is_literal,dtype,lang).to_s end ret end def write_triple(subject,predicate,object,is_literal=false,dtype="",lang="") #if json - #end #else #(lang?"@#{lang}":'') #define the object if(is_literal) object = "\"#{object.to_s.gsub('"','%22')}\""+ (dtype.empty? ? (lang.empty? ? "": "@#{lang}" ):"^^<#{dtype}>" ) else object = ( object[0..1] == "_:" ) ? object : "<#{object}>" end #object="\"#{object[1..-2].gsub('"','\"')}\"" #define the subject subject = ( subject[0..1] == "_:" ) ? subject : "<#{subject}>" if @output @output.write "#{subject} <#{predicate}> #{object} .\n" end "#{subject} <#{predicate}> #{object} .\n" end #generates an uri with the given name def uri (name,default="") name=name.to_s if name.try(:include?, "://") return name[0..name.length-2] if name[-1,1]=="/" return name[0..name.length] else name +="/" unless (name[name.length-1..name.length-1] == ("/" || "#")) || name.try(:include?, ":") if name.index(":") #$this->ns[substr($name,0,strpos($name,':'))].$this->normalizeLocalName(substr($name,strpos($name,':')+1)) t= @object_namespaches[name.split(":")[0].to_sym] t ||="" t += "/" unless (t[t.length-1..t.length-1] == ("/" || "#") || t.blank?) || name.try(:include?, ":") return uri( t+ normalize_local_name(name.split(":")[1])+"/") else ##($default?$default:$GLOBALS['baseURI']).$this->normalizeLocalName($name)); #falls bei default hinten ein "/" ist abschneiden #default= default[0.. default.length-2] unless default[default.length-1..default.length-1] == "/" t= default.blank? ? $base_uri : default t += "/" unless t[t.length-1..t.length-1]=="/" return uri( t + normalize_local_name(name)) end end end ### returns an hash with columnname as key and datatype as value def dbd_types (model,model_attributes) #hard coded mapping look mapping table mapping = Hash[ "binary"=>"base64Binary","boolean"=>"boolean","date"=>"date","datetime"=>"dateTime","decimal"=>"decimal","float"=>"float","integer"=>"integer","string"=>"string","text"=>"string","time"=>"time","timestamp"=>"dateTime",] dtypes = Hash.new model.columns_hash.each_key do |m| #make xsd datatye dtypes[m.to_s] ="xsd:#{mapping[model.columns_hash[m].type.to_s] }" end #replace mapping model_attributes.each do |k,v| dtypes[k.to_s]=dtypes[v.to_s] end dtypes end #some encoding stuff def normalize_local_name name CGI::escape(name).gsub(/%2F/,'/').gsub(/%23/,'#') end end