rdf 1.1.0p4 → 1.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +6 -14
- data/README +33 -33
- data/VERSION +1 -1
- data/lib/rdf.rb +60 -12
- data/lib/rdf/cli.rb +7 -1
- data/lib/rdf/cli/vocab-loader.rb +240 -0
- data/lib/rdf/format.rb +2 -2
- data/lib/rdf/mixin/enumerable.rb +12 -4
- data/lib/rdf/mixin/queryable.rb +13 -13
- data/lib/rdf/model/graph.rb +5 -4
- data/lib/rdf/model/list.rb +15 -4
- data/lib/rdf/model/literal.rb +2 -1
- data/lib/rdf/model/statement.rb +10 -1
- data/lib/rdf/model/term.rb +8 -0
- data/lib/rdf/model/uri.rb +107 -2
- data/lib/rdf/model/value.rb +8 -0
- data/lib/rdf/ntriples/reader.rb +5 -4
- data/lib/rdf/query.rb +47 -12
- data/lib/rdf/query/solutions.rb +29 -29
- data/lib/rdf/reader.rb +13 -3
- data/lib/rdf/repository.rb +1 -0
- data/lib/rdf/util/file.rb +86 -6
- data/lib/rdf/vocab.rb +158 -58
- data/lib/rdf/vocab/cc.rb +28 -11
- data/lib/rdf/vocab/cert.rb +127 -9
- data/lib/rdf/vocab/dc.rb +242 -60
- data/lib/rdf/vocab/dc11.rb +42 -20
- data/lib/rdf/vocab/doap.rb +121 -42
- data/lib/rdf/vocab/exif.rb +540 -165
- data/lib/rdf/vocab/foaf.rb +353 -66
- data/lib/rdf/vocab/geo.rb +40 -10
- data/lib/rdf/vocab/gr.rb +1094 -0
- data/lib/rdf/vocab/http.rb +81 -23
- data/lib/rdf/vocab/ical.rb +361 -0
- data/lib/rdf/vocab/ma.rb +281 -69
- data/lib/rdf/vocab/og.rb +98 -0
- data/lib/rdf/vocab/owl.rb +226 -56
- data/lib/rdf/vocab/prov.rb +489 -0
- data/lib/rdf/vocab/rdfs.rb +38 -14
- data/lib/rdf/vocab/rsa.rb +25 -9
- data/lib/rdf/vocab/rss.rb +29 -11
- data/lib/rdf/vocab/schema.rb +3729 -647
- data/lib/rdf/vocab/sioc.rb +224 -89
- data/lib/rdf/vocab/skos.rb +141 -33
- data/lib/rdf/vocab/skosxl.rb +43 -0
- data/lib/rdf/vocab/v.rb +154 -0
- data/lib/rdf/vocab/vcard.rb +337 -0
- data/lib/rdf/vocab/void.rb +142 -0
- data/lib/rdf/vocab/wdrs.rb +129 -0
- data/lib/rdf/vocab/wot.rb +52 -18
- data/lib/rdf/vocab/xhtml.rb +3 -6
- data/lib/rdf/vocab/xhv.rb +239 -0
- data/lib/rdf/writer.rb +3 -3
- metadata +81 -14
checksums.yaml
CHANGED
@@ -1,15 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
metadata.gz: !binary |-
|
9
|
-
NmU4YjMwMzUxMmNjZTViYWNjZTQ2ZjU1MzdjZWRmYzY1ZmQ2OTUyYzU0N2Zm
|
10
|
-
YzYzYmY5Y2FkMmY3MjVjNzUyZjZhOTc2MWUyOWI4NTgwN2Q3MzA4ZjJjNTk0
|
11
|
-
MmUzOTNhNGU3ZTY3NjI4NzQ2NTllMzk1YjliZjljNzA4ZDQzM2I=
|
12
|
-
data.tar.gz: !binary |-
|
13
|
-
MGY0NzJjZTJmM2M0YjQ1ZTRmM2UyYTBiM2RmYjBlZWNmMzZiZjE5ZDkxYWVm
|
14
|
-
NzMxZTE4MDUxYWZhYTc3MDhkODQ3NTY3YzNiNTZkNzQ3ZWVjODFkYzVkMDAz
|
15
|
-
YjA2ZjkyOTU5YjI1NzlhY2U3OGYzZTU2YmUzMDhiM2ExZmVmMjI=
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 636560fdd9893b6be15ec6aa259dde6b2af2c86e
|
4
|
+
data.tar.gz: af38349d48ebb7fd97aa7b20942a2dbb380b3b80
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 36b838c62356a7d6d7d31efb4246e1d24e5ee277f79f41f94ed5f908b64e310312387e711e7f14b7b4cfdce79c3f135b164c1f8c4d057a505c320e6799fda7be
|
7
|
+
data.tar.gz: 19318c68a807d1f9f3e6d9c3857c48a40ca99e51124d308b0604cdecf147fd5c37e65751845d16e491ca5f0965857881704f3faf690666ed800e43aa1218fad4
|
data/README
CHANGED
@@ -38,36 +38,26 @@ This version of RDF.rb is fully compatible with [RDF 1.1][], but it creates some
|
|
38
38
|
marginal incompatibilities with [RDF 1.0][], as implemented in versions prior to
|
39
39
|
the 1.1 release of RDF.rb:
|
40
40
|
|
41
|
-
* Introduces {RDF::IRI}, as a synonym for {RDF::URI} either {RDF::IRI} or {RDF::URI} can be used interchangeably.
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
* {RDF::List}
|
46
|
-
|
47
|
-
|
48
|
-
* {RDF::
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
* {RDF::
|
54
|
-
|
55
|
-
|
56
|
-
* {RDF::
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
this to being only {RDF::IRI}.
|
62
|
-
* There are substantial and somewhat incompatible changes to {RDF::Literal}. In [RDF 1.1][],
|
63
|
-
all literals are typed, including plain literals and language tagged literals.
|
64
|
-
Internally, plain literals are given the `xsd:string` datatype and language tagged
|
65
|
-
literals are given the `rdf:langString` datatype. Creating a plain literal, without
|
66
|
-
a datatype or language, will automatically provide the `xsd:string` datatype; similar
|
67
|
-
for language tagged literals. Note that most serialization formats will remove this
|
68
|
-
datatype. Code which depends on a literal having the `xsd:string` datatype being different
|
69
|
-
from a plain literal (formally, without a datatype) may break. However note that the
|
70
|
-
`#has\_datatype?` will continue to return `false` for plain or language-tagged literals.
|
41
|
+
* Introduces {RDF::IRI}, as a synonym for {RDF::URI} either {RDF::IRI} or {RDF::URI} can be used interchangeably. Versions of RDF.rb prior to the 1.1 release were already compatible with IRIs. Internationalized Resource Identifiers (see [RFC3987][]) are a super-set of URIs (see [RFC3986][]) which allow for characters other than standard US-ASCII.
|
42
|
+
* {RDF::URI} no longer uses the `Addressable` gem. As URIs typically don't need to be parsed, this provides a substantial performance improvement when enumerating or querying graphs and repositories.
|
43
|
+
* {RDF::List} no longer emits a `rdf:List` type. However, it will now recognize any subjects that are {RDF::Node} instances as being list elements, as long as they have both `rdf:first` and `rdf:rest` predicates.
|
44
|
+
* {RDF::Graph} adding a `context` to a graph may only be done when the underlying storage model supports contexts (the default {RDF::Repository} does). The notion of `context` in RDF.rb is treated equivalently to [Named Graphs](http://www.w3.org/TR/rdf11-concepts/#dfn-named-graph) within an RDF Dataset, and graphs on their own are not named.
|
45
|
+
* {RDF::Graph}, {RDF::Statement} and {RDF::List} now include {RDF::Value}, and not {RDF::Resource}. Made it clear that using {RDF::Graph} does not mean that it may be used within an {RDF::Statement}, for this see {RDF::Term}.
|
46
|
+
* {RDF::Statement} now is stricter about checking that all elements are valid when validating.
|
47
|
+
* {RDF::NTriples::Writer} and {RDF::NQuads::Writer} now default to validate output, only allowing valid statements to be emitted. This may disabled by setting the `:validate` option to `false`.
|
48
|
+
* {RDF::Dataset} is introduced as a class alias of {RDF::Repository}. This allows closer alignment to the RDF concept of [Dataset](http://www.w3.org/TR/rdf11-concepts/#dfn-dataset).
|
49
|
+
* The `context` (or `name`) of a named graph within a Dataset or Repository may be either an {RDF::IRI} or {RDF::Node}. Implementations of repositories may restrict this to being only {RDF::IRI}.
|
50
|
+
* There are substantial and somewhat incompatible changes to {RDF::Literal}. In [RDF 1.1][], all literals are typed, including plain literals and language tagged literals. Internally, plain literals are given the `xsd:string` datatype and language tagged literals are given the `rdf:langString` datatype. Creating a plain literal, without a datatype or language, will automatically provide the `xsd:string` datatype; similar for language tagged literals. Note that most serialization formats will remove this datatype. Code which depends on a literal having the `xsd:string` datatype being different from a plain literal (formally, without a datatype) may break. However note that the `#has\_datatype?` will continue to return `false` for plain or language-tagged literals.
|
51
|
+
* {RDF::Query#execute} now accepts a block and returns {RDF::Query::Solutions}. This allows `enumerable.query(query)` to behave like `query.execute(enumerable)` and either return an enumerable or yield each solution.
|
52
|
+
* {RDF::Queryable#query} now returns {RDF::Query::Solutions} instead of an Enumerator if it's argument is an {RDF::Query}.
|
53
|
+
* {RDF::Util::File.open\_file} now performs redirects and manages `base_uri` based on W3C recommendations:
|
54
|
+
* `base_uri` is set to the original URI if a status 303 is provided, otherwise any other redirect will set `base_uri` to the redirected location.
|
55
|
+
* `base_uri` is set to the content of the `Location` header if status is _success_.
|
56
|
+
* Additionally, {RDF::Util::File.open\_file} sets the result encoding from `charset` if provided, defaulting to `UTF-8`. Other access methods include `last_modified` and `content_type`,
|
57
|
+
* {RDF::StrictVocabulary} added with an easy way to keep vocabulary definitions up to date based on their OWL or RDFS definitions. Most vocabularies are now StrictVocabularies meaning that an attempt to resolve a particular term in that vocabulary will error if the term is not defined in the vocabulary.
|
58
|
+
* New vocabulary definitions have been added for [ICal](http://www.w3.org/2002/12/cal/icaltzd#), [Media Annotations (MA)](http://www.w3.org/ns/ma-ont#), [Facebook OpenGraph (OG)](http://ogp.me/ns#), [PROV](http://www.w3.org/ns/prov#), [SKOS-XL (SKOSXL)](http://www.w3.org/2008/05/skos-xl#), [Data Vocabulary (V)](http://rdf.data-vocabulary.org/), [VCard](http://www.w3.org/2006/vcard/ns#), [VOID](http://rdfs.org/ns/void#http://rdfs.org/ns/void#), [Powder-S (WDRS)](http://www.w3.org/2007/05/powder-s#), and [XHV](http://www.w3.org/1999/xhtml/vocab#).
|
59
|
+
|
60
|
+
Notably, {RDF::Queryable#query} and {RDF::Query#execute} are now completely symmetric; this allows an implementation of {RDF::Queryable} to optimize queries using implementation-specific logic, allowing for substantial performance improvements when executing BGP queries.
|
71
61
|
|
72
62
|
## Tutorials
|
73
63
|
|
@@ -188,10 +178,18 @@ Note that no prefixes are loaded automatically, however they can be provided as
|
|
188
178
|
}
|
189
179
|
})
|
190
180
|
|
191
|
-
query.execute(graph)
|
181
|
+
query.execute(graph) do |solution|
|
192
182
|
puts "name=#{solution.name} email=#{solution.email}"
|
193
183
|
end
|
194
184
|
|
185
|
+
The same query may also be run from the graph:
|
186
|
+
|
187
|
+
graph.query(query) do |solution|
|
188
|
+
puts "name=#{solution.name} email=#{solution.email}"
|
189
|
+
end
|
190
|
+
|
191
|
+
In general, querying from using the `queryable` instance allows a specific implementation of `queryable` to perform query optimizations specific to the datastore on which it is based.
|
192
|
+
|
195
193
|
A separate [SPARQL][SPARQL doc] gem builds on basic BGP support to provide full support for [SPARQL 1.0](http://www.w3.org/TR/rdf-sparql-query/) queries.
|
196
194
|
|
197
195
|
### Using pre-defined RDF vocabularies
|
@@ -373,7 +371,7 @@ follows:
|
|
373
371
|
|
374
372
|
* [Arto Bendiken](http://github.com/bendiken) - <http://ar.to/>
|
375
373
|
* [Ben Lavender](http://github.com/bhuga) - <http://bhuga.net/>
|
376
|
-
* [Gregg Kellogg](http://github.com/gkellogg) - <http://
|
374
|
+
* [Gregg Kellogg](http://github.com/gkellogg) - <http://greggkellogg.net/>
|
377
375
|
|
378
376
|
## Contributors
|
379
377
|
|
@@ -392,6 +390,8 @@ follows:
|
|
392
390
|
|
393
391
|
## Contributing
|
394
392
|
|
393
|
+
This repository uses [Git Flow](https://github.com/nvie/gitflow) to mange development and release activity. All submissions _must_ be on a feature branch based on the _develop_ branch to ease staging and integration.
|
394
|
+
|
395
395
|
* Do your best to adhere to the existing coding conventions and idioms.
|
396
396
|
* Don't use hard tabs, and don't leave trailing whitespace on any line.
|
397
397
|
Before committing, run `git diff --check` to make sure of this.
|
@@ -419,7 +419,7 @@ see <http://unlicense.org/> or the accompanying {file:UNLICENSE} file.
|
|
419
419
|
[YARD-GS]: http://rubydoc.info/docs/yard/file/docs/GettingStarted.md
|
420
420
|
[PDD]: http://lists.w3.org/Archives/Public/public-rdf-ruby/2010May/0013.html
|
421
421
|
[Backports]: http://rubygems.org/gems/backports
|
422
|
-
[JSONLD doc]: http://rubydoc.info/github/
|
422
|
+
[JSONLD doc]: http://rubydoc.info/github/ruby-rdf/json-ld/frames
|
423
423
|
[LinkedData doc]: http://rubydoc.info/github/datagraph/linkeddata/master/frames
|
424
424
|
[Microdata doc]: http://rubydoc.info/github/ruby-rdf/rdf-microdata/frames
|
425
425
|
[N3 doc]: http://rubydoc.info/github/ruby-rdf/rdf-n3/master/frames
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
1.1.
|
1
|
+
1.1.0
|
data/lib/rdf.rb
CHANGED
@@ -1,5 +1,3 @@
|
|
1
|
-
require 'enumerator'
|
2
|
-
require 'open-uri'
|
3
1
|
require 'stringio'
|
4
2
|
require 'bigdecimal'
|
5
3
|
require 'date'
|
@@ -55,6 +53,7 @@ module RDF
|
|
55
53
|
|
56
54
|
# RDF vocabularies
|
57
55
|
autoload :Vocabulary, 'rdf/vocab'
|
56
|
+
autoload :StrictVocabulary, 'rdf/vocab'
|
58
57
|
VOCABS = Dir.glob(File.join(File.dirname(__FILE__), 'rdf', 'vocab', '*.rb')).map { |f| File.basename(f)[0...-(File.extname(f).size)].to_sym } rescue []
|
59
58
|
VOCABS.each { |v| autoload v.to_s.upcase.to_sym, "rdf/vocab/#{v}" unless v == :rdf }
|
60
59
|
|
@@ -116,12 +115,60 @@ module RDF
|
|
116
115
|
end
|
117
116
|
|
118
117
|
##
|
119
|
-
#
|
118
|
+
# @overload List()
|
119
|
+
# @return [RDF::URI] returns the IRI for `rdf:List`
|
120
120
|
#
|
121
|
-
# @
|
122
|
-
#
|
123
|
-
|
124
|
-
|
121
|
+
# @overload List(*args)
|
122
|
+
# @param (see RDF::List#[])
|
123
|
+
# @return [RDF::List]
|
124
|
+
#
|
125
|
+
# @overload List(array)
|
126
|
+
# @param [Array] array
|
127
|
+
# @return [RDF::List]
|
128
|
+
#
|
129
|
+
# @overload List(list)
|
130
|
+
# @param [RDF::List] list
|
131
|
+
# @return [RDF::List] returns itself
|
132
|
+
def self.List(*args)
|
133
|
+
case
|
134
|
+
when args.empty?
|
135
|
+
RDF[:List]
|
136
|
+
when args.length == 1 && args.first.is_a?(RDF::List)
|
137
|
+
args.first
|
138
|
+
when args.length == 1 && args.first.is_a?(Array)
|
139
|
+
List[*args.first]
|
140
|
+
else
|
141
|
+
List[*args]
|
142
|
+
end
|
143
|
+
end
|
144
|
+
|
145
|
+
##
|
146
|
+
# @overload Statement()
|
147
|
+
# @return [RDF::URI] returns the IRI for `rdf:Statement`
|
148
|
+
#
|
149
|
+
# @overload Statement(options = {})
|
150
|
+
# @param [Hash{Symbol => Object}] options
|
151
|
+
# @option options [RDF::Resource] :subject (nil)
|
152
|
+
# @option options [RDF::URI] :predicate (nil)
|
153
|
+
# @option options [RDF::Term] :object (nil)
|
154
|
+
# @option options [RDF::Resource] :context (nil)
|
155
|
+
# Note, in RDF 1.1, a context MUST be an IRI.
|
156
|
+
# @return [RDF::Statement]
|
157
|
+
#
|
158
|
+
# @overload Statement(subject, predicate, object, options = {})
|
159
|
+
# @param [RDF::Resource] subject
|
160
|
+
# @param [RDF::URI] predicate
|
161
|
+
# @param [RDF::Term] object
|
162
|
+
# @param [Hash{Symbol => Object}] options
|
163
|
+
# @option options [RDF::Resource] :context (nil)
|
164
|
+
# @return [RDF::Statement]
|
165
|
+
#
|
166
|
+
def self.Statement(*args)
|
167
|
+
if args.empty?
|
168
|
+
RDF[:Statement]
|
169
|
+
else
|
170
|
+
Statement.new(*args)
|
171
|
+
end
|
125
172
|
end
|
126
173
|
|
127
174
|
##
|
@@ -134,9 +181,12 @@ module RDF
|
|
134
181
|
end
|
135
182
|
|
136
183
|
##
|
137
|
-
#
|
138
|
-
|
139
|
-
|
184
|
+
# Alias for `RDF::StrictVocabulary.create`.
|
185
|
+
#
|
186
|
+
# @param (see RDF::Vocabulary#initialize)
|
187
|
+
# @return [Class]
|
188
|
+
def self.StrictVocabulary(prefix)
|
189
|
+
StrictVocabulary.create(prefix)
|
140
190
|
end
|
141
191
|
|
142
192
|
##
|
@@ -177,14 +227,12 @@ module RDF
|
|
177
227
|
first
|
178
228
|
HTML
|
179
229
|
langString
|
180
|
-
List
|
181
230
|
nil
|
182
231
|
object
|
183
232
|
predicate
|
184
233
|
Property
|
185
234
|
rest
|
186
235
|
Seq
|
187
|
-
Statement
|
188
236
|
subject
|
189
237
|
type
|
190
238
|
value
|
data/lib/rdf/cli.rb
CHANGED
@@ -6,7 +6,13 @@ begin
|
|
6
6
|
gem 'linkeddata'
|
7
7
|
require 'linkeddata'
|
8
8
|
rescue LoadError
|
9
|
-
# Silently load without linkeddata
|
9
|
+
# Silently load without linkeddata, but try some others
|
10
|
+
%w(rdfa rdfxml turtle).each do |ser|
|
11
|
+
begin
|
12
|
+
require "rdf/#{ser}"
|
13
|
+
rescue LoadError
|
14
|
+
end
|
15
|
+
end
|
10
16
|
end
|
11
17
|
|
12
18
|
class OptionParser
|
@@ -0,0 +1,240 @@
|
|
1
|
+
require 'rdf'
|
2
|
+
require 'linkeddata'
|
3
|
+
require 'optparse'
|
4
|
+
|
5
|
+
module RDF
|
6
|
+
# Utility class to load RDF vocabularies from files or their canonical
|
7
|
+
# definitions and emit either a class file for RDF::StrictVocabulary,
|
8
|
+
# RDF::Vocabulary or the raw RDF vocabulary
|
9
|
+
class VocabularyLoader
|
10
|
+
def initialize(class_name = nil)
|
11
|
+
@class_name = class_name
|
12
|
+
@output = $stdout
|
13
|
+
@output_class_file = true
|
14
|
+
@prefix = nil
|
15
|
+
@url = nil
|
16
|
+
@strict = true
|
17
|
+
@extra = []
|
18
|
+
end
|
19
|
+
attr_accessor :class_name, :output, :output_class_file
|
20
|
+
attr_reader :prefix, :source
|
21
|
+
|
22
|
+
# Set the prefix for the loaded RDF file - by default, sets the source as
|
23
|
+
# well
|
24
|
+
def prefix=(uri)
|
25
|
+
@prefix = uri
|
26
|
+
@source ||= uri
|
27
|
+
end
|
28
|
+
|
29
|
+
# Set the source for the loaded RDF - by default, sets the prefix as well
|
30
|
+
def source=(uri)
|
31
|
+
@source = uri
|
32
|
+
@prefix ||= uri
|
33
|
+
end
|
34
|
+
|
35
|
+
# Set output
|
36
|
+
def output=(out)
|
37
|
+
@output = out
|
38
|
+
end
|
39
|
+
|
40
|
+
# Extra properties to define
|
41
|
+
def extra=(extra)
|
42
|
+
@extra = extra
|
43
|
+
end
|
44
|
+
|
45
|
+
# Use StrictVocabulary or Vocabulary
|
46
|
+
def strict=(strict)
|
47
|
+
@strict = strict
|
48
|
+
end
|
49
|
+
|
50
|
+
# Parses arguments, for use in a command line tool
|
51
|
+
def parse_options(argv)
|
52
|
+
opti = OptionParser.new
|
53
|
+
opti.banner = "Usage: #{File.basename($0)} [options] [prefix [outfile]]\nFetch an RDFS file and produce an RDF::StrictVocabulary with it.\n\n"
|
54
|
+
|
55
|
+
opti.on("--prefix URI", "The prefix for the fetched RDF vocabulary") do |uri|
|
56
|
+
self.prefix = uri
|
57
|
+
end
|
58
|
+
|
59
|
+
opti.on("--source SOURCE", "The source URI or file for the vocabulary") do |uri|
|
60
|
+
self.source = uri
|
61
|
+
end
|
62
|
+
|
63
|
+
opti.on("--class-name NAME", "The class name for the output StrictVocabulary subclass") do |name|
|
64
|
+
self.class_name = name
|
65
|
+
end
|
66
|
+
|
67
|
+
opti.on("--raw", "Don't output an output file - just the RDF") do
|
68
|
+
@output_class_file = false
|
69
|
+
end
|
70
|
+
|
71
|
+
opti.on_tail("--help", "This help text") do
|
72
|
+
$stdout.puts opti
|
73
|
+
exit 1
|
74
|
+
end
|
75
|
+
|
76
|
+
others = opti.parse(argv)
|
77
|
+
|
78
|
+
if @class_name.nil? and @output_class_file
|
79
|
+
raise "Class name (--class-name) is required!"
|
80
|
+
end
|
81
|
+
|
82
|
+
if prefix.nil?
|
83
|
+
self.prefix, outfile, extra = *others
|
84
|
+
else
|
85
|
+
outfile, extra = *others
|
86
|
+
end
|
87
|
+
|
88
|
+
unless outfile.nil?
|
89
|
+
@output = File.open(outfile, "w")
|
90
|
+
end
|
91
|
+
|
92
|
+
unless extra.nil?
|
93
|
+
$stderr.puts "Too many arguments!"
|
94
|
+
$stderr.puts opti
|
95
|
+
exit 1
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
99
|
+
# Loads the graph
|
100
|
+
def graph
|
101
|
+
@graph ||= RDF::Graph.load(source)
|
102
|
+
end
|
103
|
+
|
104
|
+
# Parse command line arguments and run the load-and-emit process
|
105
|
+
def go(argv)
|
106
|
+
parse_options(argv)
|
107
|
+
run
|
108
|
+
|
109
|
+
if @output != $stdout
|
110
|
+
@output.close
|
111
|
+
end
|
112
|
+
end
|
113
|
+
|
114
|
+
# @private
|
115
|
+
def from_solution(solution)
|
116
|
+
prefix_match = %r{\A#{@prefix}(.*)}
|
117
|
+
return if !solution.resource.uri? || (match = prefix_match.match(solution.resource.to_s)).nil?
|
118
|
+
name = match[1]
|
119
|
+
|
120
|
+
# If there's a label or comment, the must either have no language, or be en
|
121
|
+
label = solution[:label]
|
122
|
+
comment = solution[:comment]
|
123
|
+
|
124
|
+
return if label && label.has_language? && !label.language.to_s.start_with?("en")
|
125
|
+
return if comment && comment.has_language? && !comment.language.to_s.start_with?("en")
|
126
|
+
label = label.to_s.
|
127
|
+
encode(Encoding::US_ASCII). # also force exception if invalid
|
128
|
+
strip.
|
129
|
+
gsub(/\s+/m, ' ')
|
130
|
+
comment = comment.to_s.
|
131
|
+
encode(Encoding::US_ASCII). # also force exception if invalid
|
132
|
+
strip.
|
133
|
+
gsub(/\s+/m, ' ').
|
134
|
+
gsub(/([\(\)])/, '\\\\\\1')
|
135
|
+
|
136
|
+
@output.write " property #{name.to_sym.inspect}"
|
137
|
+
@output.write ", :label => '#{label}'" unless label.empty?
|
138
|
+
@output.write ", :comment =>\n %(#{comment.scan(/\S.{0,60}\S(?=\s|$)|\S+/).join("\n ")})" unless comment.empty?
|
139
|
+
@output.puts
|
140
|
+
rescue Encoding::UndefinedConversionError
|
141
|
+
end
|
142
|
+
|
143
|
+
# Actually executes the load-and-emit process - useful when using this
|
144
|
+
# class outside of a command line - instantiate, set attributes manually,
|
145
|
+
# then call #run
|
146
|
+
def run
|
147
|
+
@output.print %(# This file generated automatically using vocab-fetch from #{source}
|
148
|
+
require 'rdf'
|
149
|
+
module RDF
|
150
|
+
class #{class_name} < #{"Strict" if @strict}Vocabulary("#{prefix}")
|
151
|
+
).gsub(/^ /, '') if @output_class_file
|
152
|
+
|
153
|
+
classes = RDF::Query.new do
|
154
|
+
pattern [:resource, RDF.type, RDFS.Class]
|
155
|
+
pattern [:resource, RDFS.label, :label], :optional => true
|
156
|
+
pattern [:resource, RDFS.comment, :comment], :optional => true
|
157
|
+
end
|
158
|
+
|
159
|
+
owl_classes = RDF::Query.new do
|
160
|
+
pattern [:resource, RDF.type, OWL.Class]
|
161
|
+
pattern [:resource, RDFS.label, :label], :optional => true
|
162
|
+
pattern [:resource, RDFS.comment, :comment], :optional => true
|
163
|
+
end
|
164
|
+
|
165
|
+
class_defs = graph.query(classes).to_a + graph.query(owl_classes).to_a
|
166
|
+
unless class_defs.empty?
|
167
|
+
@output.puts "\n # Class definitions"
|
168
|
+
class_defs.sort_by {|s| (s[:label] || s[:resource]).to_s}.each do |klass|
|
169
|
+
from_solution(klass)
|
170
|
+
end
|
171
|
+
end
|
172
|
+
|
173
|
+
properties = RDF::Query.new do
|
174
|
+
pattern [:resource, RDF.type, RDF.Property]
|
175
|
+
pattern [:resource, RDFS.label, :label], :optional => true
|
176
|
+
pattern [:resource, RDFS.comment, :comment], :optional => true
|
177
|
+
end
|
178
|
+
|
179
|
+
dt_properties = RDF::Query.new do
|
180
|
+
pattern [:resource, RDF.type, OWL.DatatypeProperty]
|
181
|
+
pattern [:resource, RDFS.label, :label], :optional => true
|
182
|
+
pattern [:resource, RDFS.comment, :comment], :optional => true
|
183
|
+
end
|
184
|
+
|
185
|
+
obj_properties = RDF::Query.new do
|
186
|
+
pattern [:resource, RDF.type, OWL.ObjectProperty]
|
187
|
+
pattern [:resource, RDFS.label, :label], :optional => true
|
188
|
+
pattern [:resource, RDFS.comment, :comment], :optional => true
|
189
|
+
end
|
190
|
+
|
191
|
+
ann_properties = RDF::Query.new do
|
192
|
+
pattern [:resource, RDF.type, OWL.AnnotationProperty]
|
193
|
+
pattern [:resource, RDFS.label, :label], :optional => true
|
194
|
+
pattern [:resource, RDFS.comment, :comment], :optional => true
|
195
|
+
end
|
196
|
+
|
197
|
+
ont_properties = RDF::Query.new do
|
198
|
+
pattern [:resource, RDF.type, OWL.OntologyProperty]
|
199
|
+
pattern [:resource, RDFS.label, :label], :optional => true
|
200
|
+
pattern [:resource, RDFS.comment, :comment], :optional => true
|
201
|
+
end
|
202
|
+
prop_defs = graph.query(properties).to_a.sort_by {|s| (s[:label] || s[:resource]).to_s}
|
203
|
+
prop_defs += graph.query(dt_properties).to_a.sort_by {|s| (s[:label] || s[:resource]).to_s}
|
204
|
+
prop_defs += graph.query(obj_properties).to_a.sort_by {|s| (s[:label] || s[:resource]).to_s}
|
205
|
+
prop_defs += graph.query(ann_properties).to_a.sort_by {|s| (s[:label] || s[:resource]).to_s}
|
206
|
+
prop_defs += graph.query(ont_properties).to_a.sort_by {|s| (s[:label] || s[:resource]).to_s}
|
207
|
+
unless prop_defs.empty?
|
208
|
+
@output.puts "\n # Property definitions"
|
209
|
+
prop_defs.each do |prop|
|
210
|
+
from_solution(prop)
|
211
|
+
end
|
212
|
+
end
|
213
|
+
|
214
|
+
|
215
|
+
datatypes = RDF::Query.new do
|
216
|
+
pattern [:resource, RDF.type, RDFS.Datatype]
|
217
|
+
pattern [:resource, RDFS.label, :label], :optional => true
|
218
|
+
pattern [:resource, RDFS.comment, :comment], :optional => true
|
219
|
+
end
|
220
|
+
|
221
|
+
dt_defs = graph.query(datatypes).to_a.sort_by {|s| (s[:label] || s[:resource]).to_s}
|
222
|
+
unless dt_defs.empty?
|
223
|
+
@output.puts "\n # Datatype definitions"
|
224
|
+
dt_defs.each do |dt|
|
225
|
+
from_solution(dt)
|
226
|
+
end
|
227
|
+
end
|
228
|
+
|
229
|
+
unless @extra.empty?
|
230
|
+
@output.puts "\n # Extra definitions"
|
231
|
+
@extra.each do |extra|
|
232
|
+
@output.puts " property #{extra.to_sym.inspect}"
|
233
|
+
end
|
234
|
+
end
|
235
|
+
|
236
|
+
# Query the vocabulary to extract property and class definitions
|
237
|
+
@output.puts " end\nend" if @output_class_file
|
238
|
+
end
|
239
|
+
end
|
240
|
+
end
|