1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
|
class String
def convert_underscore
gsub(/_./) do |m|
m.gsub!(/^_/,"")
m.upcase
end
end
end
module Lib
module RDFProvider
def to_rdf
HashToOwl.to_rdf(self)
end
def uri
raise "not implemented"
end
def rdf_title
raise "not implemented"
end
# the rdf output is generated from the hash that is provided by this method
# the keys in the hash structure are used to defined type of the resource (literal, objectProperty, dataProperty)
# example: if the structure should contain a literal named "size" with value 5
# * add :property_xy => 5 to your hash
# * make sure literal?(:property_xy) returns true
# * literal_name(:property_xy) must return "size"
#
def get_content_as_hash
raise "not implemented"
end
def to_yaml
get_content_as_hash.to_yaml
end
def rdf_ignore?( prop )
self.class::IGNORE.index( prop ) != nil
end
def literal?( prop )
self.class::LITERALS.index( prop ) != nil
end
def literal_name( prop )
if self.class::LITERAL_NAMES.has_key?(prop)
self.class::LITERAL_NAMES[prop]
else
OT[prop.to_s.convert_underscore]
end
end
def object_property?( prop )
self.class::OBJECT_PROPERTIES.has_key?( prop )
end
def object_property_name( prop )
return self.class::OBJECT_PROPERTIES[ prop ]
end
def object_type( prop )
return self.class::OBJECTS[ prop ]
end
def class?(prop)
self.class::CLASSES.has_key?( prop )
end
def class_name( prop )
return self.class::CLASSES[ prop ]
end
end
class HashToOwl
#include OpenTox::Owl
def self.to_rdf( rdf_provider )
owl = OpenTox::Owl.create(rdf_provider.rdf_title, rdf_provider.uri )
toOwl = HashToOwl.new(owl)
toOwl.add_content(rdf_provider)
toOwl.rdf
end
def add_content( rdf_provider )
@rdf_provider = rdf_provider
recursiv_add_content( @rdf_provider.get_content_as_hash, @owl.root_node )
end
def rdf
@owl.rdf
end
private
def initialize(owl)
@owl = owl
@model = owl.model
end
def recursiv_add_content( output, node )
output.each do |k,v|
if v==nil
LOGGER.warn "skipping nil value: "+k.to_s
next
end
if @rdf_provider.rdf_ignore?(k)
#do nothing
elsif v.is_a?(Hash)
new_node = add_class( k, node )
recursiv_add_content( v, new_node )
elsif v.is_a?(Array)
v.each do |value|
if @rdf_provider.class?(k)
new_node = add_class( k, node )
recursiv_add_content( value, new_node )
else
add_object_property( k, value, node)
end
end
elsif @rdf_provider.literal?(k)
set_literal( k, v, node)
elsif @rdf_provider.object_property?(k)
add_object_property( k, v, node)
else
raise "illegal value k:"+k.to_s+" v:"+v.to_s
end
end
end
def add_class( property, node )
raise "no object prop: "+property.to_s unless @rdf_provider.object_property?(property)
raise "no class name: "+property.to_s unless @rdf_provider.class_name(property)
# to avoid anonymous nodes, make up uris for sub-objects
# use counter to make sure each uri is unique
# for example we will get ../confusion_matrix_cell/1, ../confusion_matrix_cell/2, ...
count = 1
while (true)
res = Redland::Resource.new( File.join(node.uri.to_s,property.to_s+"/"+count.to_s) )
break if @model.subject(@rdf_provider.object_property_name(property), res).nil?
count += 1
end
clazz = Redland::Resource.new(@rdf_provider.class_name(property))
@model.add res, RDF['type'], clazz
@model.add res, DC['title'], clazz
@model.add clazz, RDF['type'], OWL['Class']
@model.add DC['title'], RDF['type'],OWL['AnnotationProperty']
objectProp = Redland::Resource.new(@rdf_provider.object_property_name(property))
@model.add objectProp, RDF['type'], OWL['ObjectProperty']
@model.add node, objectProp, res
return res
end
def set_literal(property, value, node )
raise "empty literal value "+property.to_s if value==nil || value.to_s.size==0
raise "no literal name "+propety.to_s unless @rdf_provider.literal_name(property)
begin
l = @model.object(subject, @rdf_provider.literal_name(property))
@model.delete node, @rdf_provider.literal_name(property), l
rescue
end
literalProp = Redland::Resource.new(@rdf_provider.literal_name(property))
@model.add literalProp, RDF['type'],OWL['AnnotationProperty']
@model.add node, literalProp, Redland::Literal.create(value)
end
def add_object_property(property, value, node )
raise "empty object property value "+property.to_s if value==nil || value.to_s.size==0
raise "no object property name "+propety.to_s unless @rdf_provider.object_property_name(property)
raise "no object type "+property.to_s unless @rdf_provider.object_type(property)
objectProp = Redland::Resource.new(@rdf_provider.object_property_name(property))
@model.add objectProp, RDF['type'], OWL['ObjectProperty']
val = Redland::Resource.new(value)
type = Redland::Resource.new(@rdf_provider.object_type(property))
@model.add node, objectProp, val
@model.add val, RDF['type'], type
@model.add type, RDF['type'], OWL['Class']
end
end
end
|