yowl 0.4.pre

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (108) hide show
  1. data/CHANGES +15 -0
  2. data/INSTALL-MACOSX.md +107 -0
  3. data/README.md +92 -0
  4. data/Rakefile +76 -0
  5. data/bin/yowl +14 -0
  6. data/examples/introduction.html +5 -0
  7. data/lib/yowl/association.rb +66 -0
  8. data/lib/yowl/class.rb +296 -0
  9. data/lib/yowl/generator.rb +96 -0
  10. data/lib/yowl/import.rb +62 -0
  11. data/lib/yowl/individual.rb +398 -0
  12. data/lib/yowl/individual_association.rb +80 -0
  13. data/lib/yowl/ontology.rb +197 -0
  14. data/lib/yowl/options.rb +116 -0
  15. data/lib/yowl/optionsparser.rb +75 -0
  16. data/lib/yowl/person.rb +26 -0
  17. data/lib/yowl/property.rb +190 -0
  18. data/lib/yowl/repository.rb +100 -0
  19. data/lib/yowl/schema.rb +519 -0
  20. data/lib/yowl/template/css/jquery.ui.all.css +11 -0
  21. data/lib/yowl/template/css/smoothness/images/ui-bg_flat_0_aaaaaa_40x100.png +0 -0
  22. data/lib/yowl/template/css/smoothness/images/ui-bg_flat_75_ffffff_40x100.png +0 -0
  23. data/lib/yowl/template/css/smoothness/images/ui-bg_glass_55_fbf9ee_1x400.png +0 -0
  24. data/lib/yowl/template/css/smoothness/images/ui-bg_glass_65_ffffff_1x400.png +0 -0
  25. data/lib/yowl/template/css/smoothness/images/ui-bg_glass_75_dadada_1x400.png +0 -0
  26. data/lib/yowl/template/css/smoothness/images/ui-bg_glass_75_e6e6e6_1x400.png +0 -0
  27. data/lib/yowl/template/css/smoothness/images/ui-bg_glass_95_fef1ec_1x400.png +0 -0
  28. data/lib/yowl/template/css/smoothness/images/ui-bg_highlight-soft_75_cccccc_1x100.png +0 -0
  29. data/lib/yowl/template/css/smoothness/images/ui-icons_222222_256x240.png +0 -0
  30. data/lib/yowl/template/css/smoothness/images/ui-icons_2e83ff_256x240.png +0 -0
  31. data/lib/yowl/template/css/smoothness/images/ui-icons_454545_256x240.png +0 -0
  32. data/lib/yowl/template/css/smoothness/images/ui-icons_888888_256x240.png +0 -0
  33. data/lib/yowl/template/css/smoothness/images/ui-icons_cd0a0a_256x240.png +0 -0
  34. data/lib/yowl/template/css/smoothness/jquery-ui-1.8.23.custom.css +563 -0
  35. data/lib/yowl/template/css/yowl.css +414 -0
  36. data/lib/yowl/template/import-diagram.erb +29 -0
  37. data/lib/yowl/template/index.erb +56 -0
  38. data/lib/yowl/template/js/jquery-1.7.2.min.js +4 -0
  39. data/lib/yowl/template/js/jquery-ui-1.8.23.custom.min.js +125 -0
  40. data/lib/yowl/template/js/jquery.ui.accordion.js +611 -0
  41. data/lib/yowl/template/js/yowl.js +72 -0
  42. data/lib/yowl/template/ontology.erb +598 -0
  43. data/lib/yowl/template/themes/base/images/ui-bg_flat_0_aaaaaa_40x100.png +0 -0
  44. data/lib/yowl/template/themes/base/images/ui-bg_flat_75_ffffff_40x100.png +0 -0
  45. data/lib/yowl/template/themes/base/images/ui-bg_glass_55_fbf9ee_1x400.png +0 -0
  46. data/lib/yowl/template/themes/base/images/ui-bg_glass_65_ffffff_1x400.png +0 -0
  47. data/lib/yowl/template/themes/base/images/ui-bg_glass_75_dadada_1x400.png +0 -0
  48. data/lib/yowl/template/themes/base/images/ui-bg_glass_75_e6e6e6_1x400.png +0 -0
  49. data/lib/yowl/template/themes/base/images/ui-bg_glass_95_fef1ec_1x400.png +0 -0
  50. data/lib/yowl/template/themes/base/images/ui-bg_highlight-soft_75_cccccc_1x100.png +0 -0
  51. data/lib/yowl/template/themes/base/images/ui-icons_222222_256x240.png +0 -0
  52. data/lib/yowl/template/themes/base/images/ui-icons_2e83ff_256x240.png +0 -0
  53. data/lib/yowl/template/themes/base/images/ui-icons_454545_256x240.png +0 -0
  54. data/lib/yowl/template/themes/base/images/ui-icons_888888_256x240.png +0 -0
  55. data/lib/yowl/template/themes/base/images/ui-icons_cd0a0a_256x240.png +0 -0
  56. data/lib/yowl/template/themes/base/jquery.ui.accordion.css +19 -0
  57. data/lib/yowl/template/themes/base/jquery.ui.all.css +11 -0
  58. data/lib/yowl/template/themes/base/jquery.ui.autocomplete.css +53 -0
  59. data/lib/yowl/template/themes/base/jquery.ui.base.css +11 -0
  60. data/lib/yowl/template/themes/base/jquery.ui.button.css +38 -0
  61. data/lib/yowl/template/themes/base/jquery.ui.core.css +38 -0
  62. data/lib/yowl/template/themes/base/jquery.ui.datepicker.css +66 -0
  63. data/lib/yowl/template/themes/base/jquery.ui.dialog.css +21 -0
  64. data/lib/yowl/template/themes/base/jquery.ui.progressbar.css +11 -0
  65. data/lib/yowl/template/themes/base/jquery.ui.resizable.css +20 -0
  66. data/lib/yowl/template/themes/base/jquery.ui.selectable.css +10 -0
  67. data/lib/yowl/template/themes/base/jquery.ui.slider.css +24 -0
  68. data/lib/yowl/template/themes/base/jquery.ui.tabs.css +18 -0
  69. data/lib/yowl/template/themes/base/jquery.ui.theme.css +247 -0
  70. data/lib/yowl/template/themes/smoothness/images/ui-bg_flat_0_aaaaaa_40x100.png +0 -0
  71. data/lib/yowl/template/themes/smoothness/images/ui-bg_flat_75_ffffff_40x100.png +0 -0
  72. data/lib/yowl/template/themes/smoothness/images/ui-bg_glass_55_fbf9ee_1x400.png +0 -0
  73. data/lib/yowl/template/themes/smoothness/images/ui-bg_glass_65_ffffff_1x400.png +0 -0
  74. data/lib/yowl/template/themes/smoothness/images/ui-bg_glass_75_dadada_1x400.png +0 -0
  75. data/lib/yowl/template/themes/smoothness/images/ui-bg_glass_75_e6e6e6_1x400.png +0 -0
  76. data/lib/yowl/template/themes/smoothness/images/ui-bg_glass_95_fef1ec_1x400.png +0 -0
  77. data/lib/yowl/template/themes/smoothness/images/ui-bg_highlight-soft_75_cccccc_1x100.png +0 -0
  78. data/lib/yowl/template/themes/smoothness/images/ui-icons_222222_256x240.png +0 -0
  79. data/lib/yowl/template/themes/smoothness/images/ui-icons_2e83ff_256x240.png +0 -0
  80. data/lib/yowl/template/themes/smoothness/images/ui-icons_454545_256x240.png +0 -0
  81. data/lib/yowl/template/themes/smoothness/images/ui-icons_888888_256x240.png +0 -0
  82. data/lib/yowl/template/themes/smoothness/images/ui-icons_cd0a0a_256x240.png +0 -0
  83. data/lib/yowl/template/themes/smoothness/jquery-ui-1.8.23.custom.css +563 -0
  84. data/lib/yowl/template/themes/smoothness/jquery.ui.accordion.css +19 -0
  85. data/lib/yowl/template/themes/smoothness/jquery.ui.all.css +11 -0
  86. data/lib/yowl/template/themes/smoothness/jquery.ui.autocomplete.css +53 -0
  87. data/lib/yowl/template/themes/smoothness/jquery.ui.base.css +11 -0
  88. data/lib/yowl/template/themes/smoothness/jquery.ui.button.css +38 -0
  89. data/lib/yowl/template/themes/smoothness/jquery.ui.core.css +38 -0
  90. data/lib/yowl/template/themes/smoothness/jquery.ui.datepicker.css +66 -0
  91. data/lib/yowl/template/themes/smoothness/jquery.ui.dialog.css +21 -0
  92. data/lib/yowl/template/themes/smoothness/jquery.ui.progressbar.css +11 -0
  93. data/lib/yowl/template/themes/smoothness/jquery.ui.resizable.css +20 -0
  94. data/lib/yowl/template/themes/smoothness/jquery.ui.selectable.css +10 -0
  95. data/lib/yowl/template/themes/smoothness/jquery.ui.slider.css +24 -0
  96. data/lib/yowl/template/themes/smoothness/jquery.ui.tabs.css +18 -0
  97. data/lib/yowl/template/themes/smoothness/jquery.ui.theme.css +249 -0
  98. data/lib/yowl/util.rb +221 -0
  99. data/lib/yowl/version.rb +3 -0
  100. data/lib/yowl.rb +42 -0
  101. data/test/input/base-with-comments.ttl +163 -0
  102. data/test/input/base.ttl +221 -0
  103. data/test/input/empty.ttl +8 -0
  104. data/test/input/example.ttl +73 -0
  105. data/test/test_example_ttl.rb +62 -0
  106. data/test/test_yowl.rb +4 -0
  107. data/test/testcases.md +24 -0
  108. metadata +311 -0
@@ -0,0 +1,96 @@
1
+ module YOWL
2
+
3
+ class Generator
4
+
5
+ def initialize(repository, options)
6
+ @options = options
7
+ @repository = repository
8
+ end
9
+
10
+ private
11
+ def generateOntologyHtmlFiles()
12
+ @repository.schemas.values.each() do |schema|
13
+ generateOntologyHtmlFile(schema)
14
+ end
15
+ end
16
+
17
+ private
18
+ def generateOntologyHtmlFile(schema)
19
+ if @options.verbose
20
+ puts "Generating documentation for ontology #{schema.ontology.title}"
21
+ end
22
+
23
+ introduction = @introduction
24
+ repository = @repository
25
+
26
+ b = binding
27
+
28
+ begin
29
+ Dir.mkdir(@options.output_dir)
30
+ rescue Errno::EEXIST
31
+ end
32
+
33
+ ontologyFile = File.join(@options.output_dir, "#{schema.name}.html")
34
+ if @options.verbose
35
+ puts "Generating #{ontologyFile}"
36
+ end
37
+ File.open(ontologyFile, 'w') do |file|
38
+ file.write(@options.templates['ontology'].result(b))
39
+ end
40
+ end
41
+
42
+ private
43
+ def generateHtmlFile(templateName_)
44
+
45
+ template = @options.templates[templateName_]
46
+
47
+ if template.nil?
48
+ puts "Not generating #{templateName_}.html since #{templateName_} template could not be found."
49
+ return
50
+ end
51
+ fileName = File.join(@options.output_dir, "#{templateName_}.html")
52
+ if @options.verbose
53
+ puts "Generating #{fileName}"
54
+ end
55
+
56
+ repository = @repository
57
+ schemas = @repository.schemas.values
58
+ ontologies = @repository.ontologies()
59
+
60
+ b = binding
61
+
62
+ File.open(fileName, 'w') do |file|
63
+ file.write(template.result(b))
64
+ end
65
+ end
66
+
67
+ private
68
+ def copyTemplateDir(src_, tgt_)
69
+ if Dir[src_] == []
70
+ return
71
+ end
72
+ puts "Copying #{src_} -> #{tgt_}"
73
+ FileUtils.cp_r src_, tgt_
74
+ end
75
+
76
+ private
77
+ def copyTemplates()
78
+
79
+ @options.template_dirs.each do |template_dir|
80
+ copyTemplateDir("#{template_dir}/js", "#{@options.output_dir}")
81
+ copyTemplateDir("#{template_dir}/css", "#{@options.output_dir}")
82
+ copyTemplateDir("#{template_dir}/themes", "#{@options.output_dir}")
83
+ copyTemplateDir("#{template_dir}/img", "#{@options.output_dir}")
84
+ end
85
+ end
86
+
87
+ public
88
+ def run()
89
+ copyTemplates()
90
+ generateHtmlFile('index')
91
+ generateHtmlFile('introduction')
92
+ generateHtmlFile('import-diagram')
93
+ generateOntologyHtmlFiles()
94
+ end
95
+ end
96
+ end
@@ -0,0 +1,62 @@
1
+ require 'yowl'
2
+
3
+ module YOWL
4
+
5
+ class Import < YOWL::LabelledDocObject
6
+
7
+ attr_reader :importedSchema
8
+ attr_reader :importedOntology
9
+
10
+ def initialize(resource_, schema_)
11
+ super(resource_, schema_)
12
+
13
+ @importedSchema = schema_.repository.getSchemaForImport(self)
14
+ @importedOntology = @importedSchema ? @importedSchema.ontology : nil
15
+
16
+ if @importedSchema.nil?
17
+ puts "WARNING: #{@schema.fileName}: Created Import #{uri} but did not find schema for it "
18
+ end
19
+ if @importedOntology.nil?
20
+ puts "WARNING: #{@schema.fileName}: Created Import #{uri} but did not find ontology for it "
21
+ end
22
+ end
23
+
24
+ def name
25
+ if @importedSchema
26
+ return @importedSchema.name
27
+ end
28
+ prefix, ns = @schema.prefixForNamespace(uri)
29
+ if prefix
30
+ return prefix
31
+ end
32
+ return short_name
33
+ end
34
+
35
+ def resourceNameHtml
36
+ return "#{@name}.html"
37
+ end
38
+
39
+ def imports
40
+ return @importedOntology ? @importedOntology.imports : []
41
+ end
42
+
43
+ def isExternal?
44
+ return (@importedSchema.nil? and @importedOntology.nil?)
45
+ end
46
+
47
+ #
48
+ # See YOWL::Individual::classWithURI(uri)
49
+ #
50
+ def classWithURI(uri_)
51
+ if isExternal?
52
+ return nil
53
+ end
54
+ if @importedSchema
55
+ return @importedSchema.classWithURI(uri_)
56
+ end
57
+ puts "WARNING: Cannot check whether class #{uri_.to_s} exists in imported ontology #{uri} as this ontology is not loaded"
58
+ return nil
59
+ end
60
+
61
+ end
62
+ end
@@ -0,0 +1,398 @@
1
+ module YOWL
2
+ #
3
+ # Represents an Individual defined in the schema
4
+ #
5
+ class Individual < YOWL::LabelledDocObject
6
+
7
+ private
8
+ def initialize(resource, schema)
9
+ super(resource, schema)
10
+ if schema.options.verbose
11
+ puts "Created Individual #{short_name}"
12
+ end
13
+ end
14
+
15
+ public
16
+ def Individual.withUri(resource, schema)
17
+ if resource.anonymous?
18
+ warn "WARNING: Ignoring Individual with uri #{resource.to_s}"
19
+ return
20
+ end
21
+ individual = schema.individuals[resource.to_s]
22
+ if individual
23
+ return individual
24
+ end
25
+ individual = Individual.new(resource, schema)
26
+ schema.individuals[resource.to_s] = individual
27
+ return individual
28
+ end
29
+
30
+ public
31
+ #
32
+ # This label is a bit different than the one in the base class as this one
33
+ # gets its prefix stripped, if there is one.
34
+ #
35
+ def label
36
+ @label ||= init_label
37
+ end
38
+
39
+ private
40
+ def init_label
41
+ label = get_literal(YOWL::Namespaces::RDFS.label)
42
+ if label
43
+ return label
44
+ end
45
+ label = short_name
46
+ label = label.sub(/(.*)\s*:/, "")
47
+ label = label.gsub("_", " ")
48
+
49
+ label.sub!(/^r29-/, "") # TODO: Make this configurable via setting in ontology
50
+
51
+ classes.each do |klass|
52
+ className = klass.short_name
53
+ label.chomp!("-#{className}")
54
+ className.sub!(/.*:/, '')
55
+ label.chomp!("-#{className}")
56
+ end
57
+
58
+ return label
59
+ end
60
+
61
+ private
62
+ def gvLabel
63
+ tmp = label.gsub(", ", ",\n")
64
+ return prefix ? "#{tmp}\n(#{prefix})" : tmp
65
+ end
66
+
67
+ public
68
+ #
69
+ # The prefix to be used for the URI of this Individual, if defined, nil if it isn't
70
+ #
71
+ def prefix
72
+ @prefix ||= init_prefix
73
+ end
74
+
75
+ private
76
+ def init_prefix
77
+ name = short_name
78
+ return name.include?(':') ? short_name.sub(/:\s*(.*)/, "") : nil
79
+ end
80
+
81
+ public
82
+ def types
83
+ if not defined?(@types)
84
+ init_types
85
+ end
86
+ return @types
87
+ end
88
+
89
+ private
90
+ def init_types
91
+ @types = []
92
+ @schema.model.query(
93
+ RDF::Query::Pattern.new(@resource, RDF.type)
94
+ ) do |statement|
95
+ if statement.object == YOWL::Namespaces::OWL.NamedIndividual
96
+ next
97
+ end
98
+ @types << statement.object
99
+ if @schema.options.verbose
100
+ puts "Found Type #{statement.object.to_s} for Individual #{label}"
101
+ end
102
+ end
103
+ end
104
+
105
+ public
106
+ def classes
107
+ if not defined?(@classes)
108
+ init_classes
109
+ end
110
+ return @classes
111
+ end
112
+
113
+ private
114
+ def init_classes
115
+ @classes = []
116
+ types.each do |type|
117
+ klass = @schema.classWithURI(type)
118
+ if klass
119
+ @classes << klass
120
+ if @schema.options.verbose
121
+ puts "Found Class #{klass.short_name} for Individual #{label}"
122
+ end
123
+ else
124
+ puts "WARNING: Could not find Class definition for URI #{type.to_s}"
125
+ end
126
+ end
127
+ end
128
+
129
+ public
130
+ def isSkosConceptScheme?
131
+ conceptSchemeClassURI = YOWL::Namespaces::SKOS.ConceptScheme.to_s
132
+ types.each do |type|
133
+ #puts "isSkosConceptScheme #{type.to_s} #{conceptSchemeClassURI}"
134
+ if type.to_s == conceptSchemeClassURI
135
+ return true
136
+ end
137
+ end
138
+ return false
139
+ end
140
+
141
+ public
142
+ def isSkosConcept?
143
+ puts "isSkosConcept #{@resource}"
144
+ inScheme = get_literal(YOWL::Namespaces::SKOS.inScheme)
145
+ if not inScheme.nil?
146
+ return true
147
+ end
148
+ topConceptOf = get_literal(YOWL::Namespaces::SKOS.topConceptOf)
149
+ if not topConceptOf.nil?
150
+ return true
151
+ end
152
+ return false
153
+ end
154
+
155
+ public
156
+ def isSkosConceptInScheme?(conceptScheme_)
157
+ inScheme = get_literal(YOWL::Namespaces::SKOS.inScheme)
158
+ if inScheme and inScheme.uri == conceptScheme_.uri
159
+ puts "isSkosConceptInScheme #{@resource}: #{inScheme.uri}"
160
+ return true
161
+ end
162
+ return false
163
+ end
164
+
165
+ public
166
+ #
167
+ # Return a collection of Associations representing ObjectProperties
168
+ # where the current class is one of the Domain classes.
169
+ #
170
+ def associatedIndividuals
171
+ if not defined?(@associatedIndividuals)
172
+ init_associatedIndividuals
173
+ end
174
+ return @associatedIndividuals
175
+ end
176
+
177
+ private
178
+ def init_associatedIndividuals()
179
+ @associatedIndividuals = Hash.new
180
+
181
+ if @schema.options.verbose
182
+ puts "Searching for associations of Individual #{short_name}"
183
+ end
184
+
185
+ sparql = <<sparql
186
+ SELECT DISTINCT ?individual WHERE {
187
+ {
188
+ ?individual a owl:NamedIndividual .
189
+ ?individual ?predicateA <#{uri}> .
190
+ } UNION {
191
+ <#{uri}>
192
+ a owl:NamedIndividual ;
193
+ ?predicateB ?individual ;
194
+ .
195
+ ?individual a owl:NamedIndividual .
196
+ }
197
+ }
198
+ sparql
199
+ #if @schema.options.verbose
200
+ # puts " - SPARQL: #{sparql}"
201
+ #end
202
+ solutions = SPARQL.execute(sparql, @schema.model, { :prefixes => @schema.prefixes })
203
+ if @schema.options.verbose
204
+ puts " - Found #{solutions.count} associated Individuals"
205
+ end
206
+
207
+ solutions.each do |solution|
208
+ individual = Individual.withUri(solution[:individual], @schema)
209
+ if @schema.options.verbose
210
+ puts " - Found Individual #{individual.short_name}"
211
+ end
212
+ @associatedIndividuals[individual.uri] = individual
213
+ end
214
+ return @associatedIndividuals
215
+ end
216
+
217
+ #
218
+ # Return a collection of IndividualAssociations representing ObjectProperties
219
+ # where the current Individual is the subject/resource.
220
+ #
221
+ def outboundAssociations()
222
+ if defined?(@outboundAssociations)
223
+ return @outboundAssociations
224
+ end
225
+ @outboundAssociations = Set.new
226
+
227
+ if @schema.options.verbose
228
+ puts "Searching for associations of individual #{short_name}"
229
+ end
230
+
231
+ sparql = <<sparql
232
+ SELECT DISTINCT ?individual ?predicate WHERE {
233
+ <#{uri}>
234
+ a owl:NamedIndividual ;
235
+ ?predicate ?individual
236
+ .
237
+ ?individual a owl:NamedIndividual .
238
+ }
239
+ sparql
240
+
241
+ #if @schema.options.verbose
242
+ # puts " - SPARQL: #{sparql}"
243
+ #end
244
+ solutions = SPARQL.execute(sparql, @schema.model, { :prefixes => @schema.prefixes })
245
+ if @schema.options.verbose
246
+ puts " - Found #{solutions.count} associated 'outbound' Individual Associations"
247
+ end
248
+
249
+ solutions.each do |solution|
250
+ individual = Individual.withUri(solution[:individual], @schema)
251
+ predicate = solution[:predicate]
252
+ @outboundAssociations << IndividualAssociation.new(predicate, @schema, self, individual)
253
+ end
254
+ if @schema.options.verbose
255
+ puts " - Returning #{@outboundAssociations.size} associations for Individual #{short_name}"
256
+ end
257
+ return @outboundAssociations
258
+ end
259
+
260
+ #
261
+ # Return a collection of IndividualAssociations representing ObjectProperties
262
+ # where the current Individual is the object.
263
+ #
264
+ def inboundAssociations()
265
+ if defined?(@inboundAssociations)
266
+ return @inboundAssociations
267
+ end
268
+ @inboundAssociations = Set.new
269
+
270
+ if @schema.options.verbose
271
+ puts "Searching for 'inbound' associations of individual #{short_name}"
272
+ end
273
+
274
+ sparql = <<sparql
275
+ SELECT DISTINCT ?individual ?predicate WHERE {
276
+ ?individual
277
+ a owl:NamedIndividual ;
278
+ ?predicate <#{uri}>
279
+ .
280
+ }
281
+ sparql
282
+ #if @schema.options.verbose
283
+ # puts " - SPARQL: #{sparql}"
284
+ #end
285
+ solutions = SPARQL.execute(sparql, @schema.model, { :prefixes => @schema.prefixes })
286
+ if @schema.options.verbose
287
+ puts " - Found #{solutions.count} associated 'inbound' Individual Associations"
288
+ end
289
+
290
+ solutions.each do |solution|
291
+ individual = Individual.withUri(solution[:individual], @schema)
292
+ predicate = solution[:predicate]
293
+ @inboundAssociations << IndividualAssociation.new(predicate, @schema, individual, self)
294
+ end
295
+ if @schema.options.verbose
296
+ puts " - Returning #{@inboundAssociations.size} associations for Individual #{short_name}"
297
+ end
298
+ return @inboundAssociations
299
+ end
300
+
301
+ private
302
+ def labelAsGraphvizRecord
303
+ lbl = label.gsub("_", " ")
304
+ if prefix and prefix == "r29" # TODO: make configurable
305
+ prefix = nil
306
+ end
307
+ lbl = prefix.nil? ? lbl : "#{lbl} | #{prefix}"
308
+ lbl = "#{lbl} |"
309
+ classes.each do |klass|
310
+ lbl += " #{klass.short_name} |"
311
+ end
312
+ lbl.chomp!(" |")
313
+ #puts "---------#{lbl}------"
314
+ return lbl
315
+ end
316
+
317
+ public
318
+ #
319
+ # Add the current Individual as a GraphViz node to the given collection of nodes
320
+ # and to the given graph. Return the collection of nodes.
321
+ #
322
+ def addAsGraphvizNode (graph_, nodes_, edges_, level_, maxLevel_ = 0)
323
+ if level_ < 1
324
+ return nodes_, edges_
325
+ end
326
+ if @schema.options.verbose
327
+ puts "- Processing Individual #{label}"
328
+ end
329
+ #
330
+ # No need to add a node twice
331
+ #
332
+ if nodes_.has_key?(uri)
333
+ return nodes_, edges_
334
+ end
335
+ options = {
336
+ :shape => :record,
337
+ :style => "rounded,filled",
338
+ :label => labelAsGraphvizRecord,
339
+ :tooltip => uri,
340
+ :peripheries => 1,
341
+ :margin => "0.21,0.055",
342
+ :fontcolor => :black,
343
+ :fontsize => 8,
344
+ :penwidth => 0.5,
345
+ :color => :black,
346
+ :fillcolor => "#FCFCFC",
347
+ :href => "#individual_#{short_name}"
348
+ }
349
+ if level_ == maxLevel_
350
+ options[:color] = "red"
351
+ options[:penwidth] = 1
352
+ end
353
+ node = graph_.add_nodes(escaped_uri, options)
354
+ nodes_[uri] = node
355
+ node.URL = "#individual_#{short_name}"
356
+
357
+ #if hasComment?
358
+ # node.tooltip = comment
359
+ #end
360
+
361
+ #classes.each do |klass|
362
+ # nodes_, edges_ = klass.addAsGraphvizNode(graph_, nodes_, edges_)
363
+ # Class.newGraphVizEdge(graph_, node, nodes_[klass.uri], false)
364
+ #end
365
+
366
+ inboundAssociations.each do |association|
367
+ nodes_, edges_ = association.addAsGraphVizEdge(graph_, nodes_, edges_, level_ - 1)
368
+ end
369
+
370
+ outboundAssociations.each do |association|
371
+ nodes_, edges_ = association.addAsGraphVizEdge(graph_, nodes_, edges_, level_ - 1)
372
+ end
373
+
374
+ return nodes_, edges_
375
+ end
376
+
377
+ public
378
+ #
379
+ # Generate a diagram for each Individual
380
+ #
381
+ def asSvg
382
+ if @schema.options.verbose
383
+ puts "Generating SVG for Individual #{short_name}"
384
+ end
385
+
386
+ g = GraphvizUtility.setDefaults(GraphViz.new(:G, :type => :digraph))
387
+ g[:rankdir] = "LR"
388
+ g.node[:fixedsize] = false
389
+
390
+ nodes = Hash.new
391
+ edges = Hash.new
392
+
393
+ nodes, edges = addAsGraphvizNode(g, nodes, edges, 5, 5)
394
+
395
+ return GraphvizUtility.embeddableSvg(g)
396
+ end
397
+ end
398
+ end
@@ -0,0 +1,80 @@
1
+ module YOWL
2
+
3
+ class IndividualAssociation < YOWL::LabelledDocObject
4
+
5
+ attr_reader :domainIndividual
6
+ attr_reader :rangeIndividual
7
+ attr_reader :property
8
+ attr_reader :key
9
+
10
+ def initialize(resource, schema, domainIndividual, rangeIndividual)
11
+
12
+ if resource.nil?
13
+ raise "Problem"
14
+ end
15
+ super(resource, schema)
16
+
17
+ @domainIndividual = domainIndividual
18
+ @rangeIndividual = rangeIndividual
19
+
20
+ @key = "#{@domainIndividual.uri},#{@rangeIndividual.uri},#{label}".hash
21
+
22
+ #puts "Created IndividualAssociation #{@domainIndividual.uri},#{@rangeIndividual.uri}, #{uri}"
23
+ end
24
+
25
+ def label
26
+ return short_name
27
+ end
28
+
29
+ def hash
30
+ return key
31
+ end
32
+
33
+ def eql?(other)
34
+ @key.eql? other.key
35
+ end
36
+
37
+ #
38
+ # Add the current IndividualAssociation as an edge to the given GraphViz graph,
39
+ # but check whether the IndividualAssociation refers to a Domain and Range class in
40
+ # the current schema and whether the IndividualAssociation has already been added
41
+ # to the graph (by checking the given edges collection).
42
+ #
43
+ def addAsGraphVizEdge(graph_, nodes_, edges_, level_)
44
+
45
+ if level_ < 1
46
+ return nodes_, edges_
47
+ end
48
+
49
+ nodes_, edges_ = @domainIndividual.addAsGraphvizNode(graph_, nodes_, edges_, level_)
50
+ nodes_, edges_ = @rangeIndividual.addAsGraphvizNode(graph_, nodes_, edges_, level_)
51
+
52
+ if edges_.has_key?(@key)
53
+ return nodes_, edges_
54
+ end
55
+
56
+ domainIndividualNode = nodes_[@domainIndividual.uri]
57
+ rangeIndividualNode = nodes_[@rangeIndividual.uri]
58
+
59
+ #
60
+ # As the level_ parameter for the two calls to addAsGraphvizNode might have caused
61
+ # that one or both of these nodes are not generated, we have to check for this here.
62
+ #
63
+ if domainIndividualNode.nil? or rangeIndividualNode.nil?
64
+ return nodes_, edges_
65
+ end
66
+
67
+ options = {
68
+ :label => label.sub(/.*:/, ''),
69
+ :tooltip => uri.to_s,
70
+ :arrowhead => :open,
71
+ :arrowsize => 0.5,
72
+ :penwidth => 0.5
73
+ }
74
+
75
+ edges_[@key] = graph_.add_edges(domainIndividualNode, rangeIndividualNode, options)
76
+
77
+ return nodes_, edges_
78
+ end
79
+ end
80
+ end