metade-rena 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
data/README.txt ADDED
@@ -0,0 +1,48 @@
1
+ = rena
2
+
3
+ * http://github.com/tommorris/rena
4
+
5
+ == DESCRIPTION:
6
+
7
+ Rena is an RDF library for Ruby.
8
+
9
+ == FEATURES/PROBLEMS:
10
+
11
+ * Features
12
+
13
+ == SYNOPSIS:
14
+
15
+ Synopsis
16
+
17
+ == REQUIREMENTS:
18
+
19
+ * Addressable gem
20
+
21
+ == INSTALL:
22
+
23
+ * (sudo gem install rena)
24
+
25
+ == LICENSE:
26
+
27
+ (The MIT License)
28
+
29
+ Copyright (c) 2008 Tom Morris
30
+
31
+ Permission is hereby granted, free of charge, to any person obtaining
32
+ a copy of this software and associated documentation files (the
33
+ 'Software'), to deal in the Software without restriction, including
34
+ without limitation the rights to use, copy, modify, merge, publish,
35
+ distribute, sublicense, and/or sell copies of the Software, and to
36
+ permit persons to whom the Software is furnished to do so, subject to
37
+ the following conditions:
38
+
39
+ The above copyright notice and this permission notice shall be
40
+ included in all copies or substantial portions of the Software.
41
+
42
+ THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
43
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
44
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
45
+ IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
46
+ CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
47
+ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
48
+ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/Rakefile ADDED
@@ -0,0 +1,54 @@
1
+ require 'rubygems'
2
+ require 'rake'
3
+ require 'spec/rake/spectask'
4
+
5
+ task :default => [:spec]
6
+
7
+ desc "Install dependencies"
8
+ task :dependencies do
9
+ require ''
10
+ gems = ['addressable/uri', 'treetop']
11
+ gems.each do |g|
12
+ g2 = g.split('/')[0]
13
+ begin
14
+ require g
15
+ rescue
16
+ sh "sudo gem install " + g2
17
+ end
18
+ end
19
+ end
20
+
21
+ desc "Pushes to git"
22
+ task :push do
23
+ sh "git push --all"
24
+ sh "growlnotify -m \"Updates pushed\" \"Git\""
25
+ end
26
+
27
+ task :spec do
28
+ sh "spec --colour spec"
29
+ end
30
+
31
+ desc "Turns spec results into HTML and publish to web (Tom only!)"
32
+ task :spec_html do
33
+ sh "spec --format html:rena_new_spec.html spec"
34
+ sh "scp rena_new_spec.html bbcityco@bbcity.co.uk:www/tom/files/rena_new_spec.html"
35
+ sh "rm rena_new_spec.html"
36
+ end
37
+
38
+ desc "Turns spec results into local HTML"
39
+ task :spec_local do
40
+ sh "spec --format html:rena_new_spec.html spec/"
41
+ # sh "open rena_new_spec.html"
42
+ end
43
+
44
+ desc "Run specs through RCov"
45
+ Spec::Rake::SpecTask.new('coverage') do |t|
46
+ t.spec_files = FileList['spec']
47
+ t.rcov = true
48
+ t.rcov_opts = ['--exclude', 'spec,test,\/Library\/Ruby\/Gems\/1.8\/gems']
49
+ end
50
+
51
+ desc "Runs specs on JRuby"
52
+ task :jspec do
53
+ sh "jruby -S `whereis spec` --colour spec"
54
+ end
data/lib/rena/bnode.rb ADDED
@@ -0,0 +1,69 @@
1
+ module Rena
2
+ class BNode
3
+ attr_accessor :identifier
4
+ def initialize(identifier = nil)
5
+ if identifier != nil && self.valid_id?(identifier) != false
6
+ @identifier = identifier
7
+ else
8
+ @identifier = "bn" + self.hash.to_s
9
+ end
10
+ end
11
+
12
+ def eql? (other)
13
+ other.is_a?(self.class) && other.identifier == self.identifier
14
+ end
15
+
16
+ alias_method :==, :eql?
17
+
18
+ ##
19
+ # Exports the BNode in N-Triples form.
20
+ #
21
+ # ==== Example
22
+ # b = BNode.new; b.to_n3 # => returns a string of the BNode in n3 form
23
+ #
24
+ # ==== Returns
25
+ # @return [String] The BNode in n3.
26
+ #
27
+ # @author Tom Morris
28
+
29
+ def to_n3
30
+ "_:" + @identifier
31
+ end
32
+
33
+
34
+ ##
35
+ # Exports the BNode in N-Triples form.
36
+ #
37
+ # ==== Example
38
+ # b = BNode.new; b.to_ntriples # => returns a string of the BNode in N-Triples form
39
+ #
40
+ # ==== Returns
41
+ # @return [String] The BNode in N-Triples.
42
+ #
43
+ # @author Tom Morris
44
+
45
+ def to_ntriples
46
+ self.to_n3
47
+ end
48
+
49
+ ##
50
+ # Returns the identifier as a string.
51
+ #
52
+ # === Returns
53
+ # @return [String] Blank node identifier.
54
+ #
55
+ # @author Tom Morris
56
+ def to_s
57
+ @identifier
58
+ end
59
+
60
+ protected
61
+ def valid_id? name
62
+ if name =~ /^[a-zA-Z_][a-zA-Z0-9]*$/
63
+ true
64
+ else
65
+ false
66
+ end
67
+ end
68
+ end
69
+ end
@@ -0,0 +1,2 @@
1
+ class AboutEachException
2
+ end
@@ -0,0 +1,2 @@
1
+ class UriRelativeException < RuntimeError
2
+ end
data/lib/rena/graph.rb ADDED
@@ -0,0 +1,188 @@
1
+ require 'rena/namespace'
2
+ require 'rena/bnode'
3
+ require 'rena/uriref'
4
+ require 'rena/literal'
5
+ require 'rena/triple'
6
+
7
+ module Rena
8
+ class Graph
9
+ attr_accessor :triples, :nsbinding
10
+
11
+ def initialize
12
+ @triples = []
13
+ @nsbinding = {}
14
+ end
15
+
16
+ def size
17
+ @triples.size
18
+ end
19
+
20
+ def each
21
+ @triples.each { |value| yield value }
22
+ end
23
+
24
+ def [] (item)
25
+ @triples[item]
26
+ end
27
+
28
+ def each_with_subject(subject)
29
+ @triples.each do |value|
30
+ yield value if value.subject == subject
31
+ end
32
+ end
33
+
34
+ def get_resource(subject)
35
+ temp = []
36
+ each_with_subject(subject) do |value|
37
+ temp << subject
38
+ end
39
+ if temp.any?
40
+ Resource.new(temp)
41
+ end
42
+ end
43
+
44
+ ##
45
+ # Adds a triple to a graph directly from the intended subject, predicate, and object.
46
+ #
47
+ # ==== Example
48
+ # g = Graph.new; g.add_triple(BNode.new, URIRef.new("http://xmlns.com/foaf/0.1/knows"), BNode.new) # => results in the triple being added to g; returns an array of g's triples
49
+ #
50
+ # @param [URIRef, BNode] s the subject of the triple
51
+ # @param [URIRef] p the predicate of the triple
52
+ # @param [URIRef, BNode, Literal, TypedLiteral] o the object of the triple
53
+ #
54
+ # ==== Returns
55
+ # @return [Array] An array of the triples (leaky abstraction? consider returning the graph instead)
56
+ #
57
+ # @raise [Error] Checks parameter types and raises if they are incorrect.
58
+ # @author Tom Morris
59
+
60
+ def add_triple(s, p, o)
61
+ @triples += [ Triple.new(s, p, o) ]
62
+ end
63
+
64
+ ##
65
+ # Adds an extant triple to a graph
66
+ #
67
+ # ==== Example
68
+ # g = Graph.new; t = Triple.new(BNode.new, URIRef.new("http://xmlns.com/foaf/0.1/knows"), BNode.new); g << t) # => results in the triple being added to g; returns an array of g's triples
69
+ #
70
+ # @param [Triple] t the triple to be added to the graph
71
+ #
72
+ # ==== Returns
73
+ # @return [Array] An array of the triples (leaky abstraction? consider returning the graph instead)
74
+ #
75
+ # @author Tom Morris
76
+
77
+
78
+ def << (triple)
79
+ # self.add_triple(s, p, o)
80
+ @triples += [ triple ]
81
+ end
82
+
83
+ ##
84
+ # Exports the graph to RDF in N-Triples form.
85
+ #
86
+ # ==== Example
87
+ # g = Graph.new; g.add_triple(BNode.new, URIRef.new("http://xmlns.com/foaf/0.1/knows"), BNode.new); g.to_ntriples # => returns a string of the graph in N-Triples form
88
+ #
89
+ # ==== Returns
90
+ # @return [String] The graph in N-Triples.
91
+ #
92
+ # @author Tom Morris
93
+
94
+ def to_ntriples
95
+ @triples.collect do |t|
96
+ t.to_ntriples
97
+ end * "\n"
98
+ end
99
+
100
+ ##
101
+ # Creates a new namespace given a URI and the short name and binds it to the graph.
102
+ #
103
+ # ==== Example
104
+ # g = Graph.new; g.namespace("http://xmlns.com/foaf/0.1/", "foaf") # => binds the Foaf namespace to g
105
+ #
106
+ # @param [String] uri the URI of the namespace
107
+ # @param [String] short the short name of the namespace
108
+ #
109
+ # ==== Returns
110
+ # @return [Namespace] The newly created namespace.
111
+ #
112
+ # @raise [Error] Checks validity of the desired shortname and raises if it is incorrect.
113
+ # @raise [Error] Checks that the newly created Namespace is of type Namespace and raises if it is incorrect.
114
+ # @author Tom Morris
115
+
116
+ def namespace(uri, short)
117
+ self.bind Namespace.new(uri, short)
118
+ end
119
+
120
+ def bind(namespace)
121
+ if namespace.class == Namespace
122
+ @nsbinding["#{namespace.short}"] = namespace
123
+ else
124
+ raise
125
+ end
126
+ end
127
+
128
+ def has_bnode_identifier?(bnodeid)
129
+ temp_bnode = BNode.new(bnodeid)
130
+ returnval = false
131
+ @triples.each { |triple|
132
+ if triple.subject.eql?(temp_bnode)
133
+ returnval = true
134
+ break
135
+ end
136
+ if triple.object.eql?(temp_bnode)
137
+ returnval = true
138
+ break
139
+ end
140
+ }
141
+ return returnval
142
+ end
143
+
144
+ def get_bnode_by_identifier(bnodeid)
145
+ temp_bnode = BNode.new(bnodeid)
146
+ each do |triple|
147
+ if triple.subject == temp_bnode
148
+ return triple.subject
149
+ end
150
+ if triple.object == temp_bnode
151
+ return triple.object
152
+ end
153
+ end
154
+ return false
155
+ end
156
+
157
+ def get_by_type(object)
158
+ out = []
159
+ each do |t|
160
+ next unless t.is_type?
161
+ next unless case object
162
+ when String
163
+ object == t.object.to_s
164
+ when Regexp
165
+ object.match(t.object.to_s)
166
+ else
167
+ object == t.object
168
+ end
169
+ out << t.subject
170
+ end
171
+ return out
172
+ end
173
+
174
+ def join(graph)
175
+ if graph.class == Graph
176
+ graph.each { |t|
177
+ self << t
178
+ }
179
+ else
180
+ raise "join requires you provide a graph object"
181
+ end
182
+ end
183
+ # alias :add, :add_triple
184
+ # alias (=+, add_triple)
185
+ private
186
+
187
+ end
188
+ end
@@ -0,0 +1,207 @@
1
+ module Rena
2
+ class Literal
3
+ class Encoding
4
+ def self.integer
5
+ @integer ||= coerce "http://www.w3.org/2001/XMLSchema#int"
6
+ end
7
+
8
+ def self.float
9
+ @float ||= coerce "http://www.w3.org/2001/XMLSchema#float"
10
+ end
11
+
12
+ def self.string
13
+ @string ||= coerce "http://www.w3.org/2001/XMLSchema#string"
14
+ end
15
+
16
+ def self.coerce(string_or_nil)
17
+ if string_or_nil.nil? || string_or_nil == ''
18
+ the_null_encoding
19
+ else
20
+ new string_or_nil
21
+ end
22
+ end
23
+
24
+ class Null
25
+ def to_s
26
+ ''
27
+ end
28
+
29
+ def format_as_n3(content)
30
+ "\"#{content}\""
31
+ end
32
+
33
+ def format_as_trix(content)
34
+ "<plainLiteral>#{content}</plainLiteral>"
35
+ end
36
+
37
+ def inspect
38
+ "<theRena::TypeLiteral::Encoding::Null>"
39
+ end
40
+
41
+ def xmlliteral?
42
+ false
43
+ end
44
+ end
45
+
46
+ def self.the_null_encoding
47
+ @the_null_encoding ||= Null.new
48
+ end
49
+
50
+ attr_reader :value
51
+ def initialize(value)
52
+ @value = value
53
+ end
54
+
55
+ def should_quote?
56
+ @value != self.class.integer.to_s
57
+ end
58
+
59
+ def ==(other)
60
+ case other
61
+ when String
62
+ other == @value
63
+ when self.class
64
+ other.value == @value
65
+ else
66
+ false
67
+ end
68
+ end
69
+
70
+ def hash
71
+ @value.hash
72
+ end
73
+
74
+ def to_s
75
+ @value
76
+ end
77
+
78
+ def format_as_n3(content)
79
+ quoted_content = should_quote? ? "\"#{content}\"" : content
80
+ "#{quoted_content}^^<#{value}>"
81
+ end
82
+
83
+ def format_as_trix(value)
84
+ "<typedLiteral datatype=\"#{@value}\">#{value}</typedLiteral>"
85
+ end
86
+
87
+ def xmlliteral?
88
+ @value == "http://www.w3.org/1999/02/22-rdf-syntax-ns#XMLLiteral"
89
+ end
90
+ end
91
+
92
+ class Language < Encoding
93
+ def initialize(string)
94
+ @value = string.downcase
95
+ end
96
+
97
+ def clean(string)
98
+ case string
99
+ when "eng"; "en"
100
+ else string
101
+ end
102
+ end
103
+
104
+ def format_as_n3(contents)
105
+ "\"#{contents}\"@#{@value}"
106
+ end
107
+
108
+ def format_as_trix(contents)
109
+ "<plainLiteral xml:lang=\"#{@value}\">#{contents}</plainLiteral>"
110
+ end
111
+
112
+ def == (other)
113
+ case other
114
+ when String
115
+ other == @value
116
+ when self.class
117
+ other.value == @value
118
+ end
119
+ end
120
+ end
121
+
122
+ attr_accessor :contents, :encoding
123
+ def initialize(contents, encoding)
124
+ @contents = contents.to_s
125
+ unless encoding.is_a?(Encoding) || encoding.is_a?(Encoding::Null)
126
+ raise TypeError, "#{encoding.inspect} should be an instance of Encoding"
127
+ end
128
+ @encoding = encoding
129
+ end
130
+
131
+ def self.untyped(contents, language = nil)
132
+ new(contents, Language.coerce(language))
133
+ end
134
+
135
+ def self.typed(contents, encoding)
136
+ new(contents, Encoding.coerce(encoding))
137
+ end
138
+
139
+ def self.build_from(object)
140
+ new(object.to_s, infer_encoding_for(object))
141
+ end
142
+
143
+ def self.infer_encoding_for(object)
144
+ case object
145
+ when Integer; Encoding.integer
146
+ when Float; Encoding.float
147
+ else Encoding.string
148
+ end
149
+ end
150
+
151
+ require 'whatlanguage'
152
+ unless WhatLanguage.nil?
153
+ def self.infer_language_for(object)
154
+ inferred_lang = object.language
155
+ case inferred_lang
156
+ when :dutch; Language.new("nl")
157
+ when :english; Language.new("en")
158
+ when :farsi; Langauge.new("fa")
159
+ when :french; Language.new("fr")
160
+ when :german; Language.new("de")
161
+ when :pinyin; Language.new("zh-CN")
162
+ when :portugese; Language.new("pt")
163
+ when :russian; Language.new("ru")
164
+ when :spanish; Language.new("es")
165
+ when :swedish; Language.new("sv")
166
+ end
167
+ end
168
+
169
+ def self.build_from_language(object)
170
+ new(object.to_s, infer_language_for(object))
171
+ end
172
+ end
173
+
174
+ class << self
175
+ protected :new
176
+ end
177
+
178
+ def == (obj)
179
+ obj.is_a?(self.class) && obj.contents == @contents && obj.encoding == @encoding
180
+ end
181
+
182
+ def to_n3
183
+ encoding.format_as_n3(@contents)
184
+ end
185
+
186
+ ## alias_method breaks subclasses! Beware! Here be dragons!
187
+ def to_ntriples
188
+ to_n3
189
+ end
190
+
191
+ def to_trix
192
+ encoding.format_as_trix(@contents)
193
+ end
194
+
195
+ def xmlliteral?
196
+ encoding.xmlliteral?
197
+ end
198
+
199
+ def to_s
200
+ @contents.to_s
201
+ end
202
+
203
+ def lang
204
+ encoding.is_a?(Language) ? encoding : nil
205
+ end
206
+ end
207
+ end