rdf_context 0.4.8 → 0.5.0
Sign up to get free protection for your applications and to get access to all the features.
- data/History.txt +27 -0
- data/README.rdoc +22 -9
- data/Rakefile +11 -6
- data/VERSION +1 -1
- data/bin/rdf_context +12 -4
- data/lib/rdf_context.rb +3 -1
- data/lib/rdf_context/aggregate_graph.rb +86 -0
- data/lib/rdf_context/array_hacks.rb +53 -0
- data/lib/rdf_context/conjunctive_graph.rb +1 -1
- data/lib/rdf_context/exceptions.rb +9 -7
- data/lib/rdf_context/graph.rb +174 -15
- data/lib/rdf_context/literal.rb +34 -2
- data/lib/rdf_context/n3_grammar.treetop +213 -129
- data/lib/rdf_context/n3parser.rb +281 -57
- data/lib/rdf_context/namespace.rb +23 -12
- data/lib/rdf_context/parser.rb +4 -3
- data/lib/rdf_context/quoted_graph.rb +38 -0
- data/lib/rdf_context/rdfaparser.rb +2 -1
- data/lib/rdf_context/rdfxmlparser.rb +4 -3
- data/lib/rdf_context/store/abstract_sql_store.rb +4 -4
- data/lib/rdf_context/store/abstract_store.rb +5 -1
- data/lib/rdf_context/store/sqlite3_store.rb +10 -8
- data/lib/rdf_context/string_hacks.rb +44 -21
- data/lib/rdf_context/term_utils.rb +73 -4
- data/lib/rdf_context/triple.rb +32 -47
- data/lib/rdf_context/uriref.rb +33 -26
- data/spec/aggregate_graph_spec.rb +59 -0
- data/spec/conjunctive_graph_spec.rb +1 -1
- data/spec/cwm_spec.rb +32 -0
- data/spec/graph_spec.rb +114 -3
- data/spec/literal_spec.rb +107 -5
- data/spec/matchers.rb +104 -51
- data/spec/n3parser_spec.rb +798 -99
- data/spec/namespaces_spec.rb +26 -0
- data/spec/quoted_graph_spec.rb +0 -0
- data/spec/rdf_helper.rb +197 -0
- data/spec/rdfa_helper.rb +15 -11
- data/spec/rdfa_parser_spec.rb +6 -8
- data/spec/rdfxml_spec.rb +21 -28
- data/spec/spec_helper.rb +20 -0
- data/spec/sqlite3_store_spec.rb +6 -5
- data/spec/store_helper.rb +9 -1
- data/spec/string_hacks_spec.rb +14 -0
- data/spec/{rdfxml_helper.rb → swap_helper.rb} +8 -9
- data/spec/swap_spec.rb +77 -0
- data/spec/swap_test/animal.rdf +17 -0
- data/spec/swap_test/anon-prop.n3 +14 -0
- data/spec/swap_test/anonymous_loop.n3 +2 -0
- data/spec/swap_test/contexts.n3 +16 -0
- data/spec/swap_test/daml-pref.n3 +10 -0
- data/spec/swap_test/i18n/hiragana.n3 +22 -0
- data/spec/swap_test/i18n/n3string.n3 +4 -0
- data/spec/swap_test/list/itemType.rdf +12 -0
- data/spec/swap_test/lists-simple.n3 +40 -0
- data/spec/swap_test/lists.n3 +35 -0
- data/spec/swap_test/n3/n3parser.tests_n3_10001.nt +3 -0
- data/spec/swap_test/n3/n3parser.tests_n3_10002.nt +7 -0
- data/spec/swap_test/n3/n3parser.tests_n3_10003.nt +3 -0
- data/spec/swap_test/n3/n3parser.tests_n3_10004.nt +119 -0
- data/spec/swap_test/n3/n3parser.tests_n3_10005.nt +3 -0
- data/spec/swap_test/n3/n3parser.tests_n3_10006.nt +225 -0
- data/spec/swap_test/n3/n3parser.tests_n3_10007.nt +79 -0
- data/spec/swap_test/n3/n3parser.tests_n3_10008.nt +5 -0
- data/spec/swap_test/n3/n3parser.tests_n3_10009.nt +13 -0
- data/spec/swap_test/n3/n3parser.tests_n3_10010.nt +21 -0
- data/spec/swap_test/n3/n3parser.tests_n3_10011.nt +9 -0
- data/spec/swap_test/n3/n3parser.tests_n3_10012.nt +53 -0
- data/spec/swap_test/n3/n3parser.tests_n3_10013.nt +19 -0
- data/spec/swap_test/n3/n3parser.tests_n3_10014.nt +103 -0
- data/spec/swap_test/n3/n3parser.tests_n3_10015.nt +103 -0
- data/spec/swap_test/n3/n3parser.tests_n3_10016.nt +3 -0
- data/spec/swap_test/n3/n3parser.tests_n3_10017.nt +151 -0
- data/spec/swap_test/n3/n3parser.tests_n3_10018.nt +9 -0
- data/spec/swap_test/n3/n3parser.tests_n3_10019.nt +3 -0
- data/spec/swap_test/n3/n3parser.tests_n3_10020.nt +13 -0
- data/spec/swap_test/n3parser.tests +160 -0
- data/spec/swap_test/nodeID/classes.n3 +9 -0
- data/spec/swap_test/nodeID/classes.ref.rdf +15 -0
- data/spec/swap_test/nodeID/ex1.rdf +15 -0
- data/spec/swap_test/norm/fix.rdf +33 -0
- data/spec/swap_test/owl-ex.rdf +150 -0
- data/spec/swap_test/ref/animal.n3 +11 -0
- data/spec/swap_test/ref/anon-prop-1.n3 +8 -0
- data/spec/swap_test/ref/anonymous_loop.ref +7 -0
- data/spec/swap_test/ref/bnode.n3 +6 -0
- data/spec/swap_test/ref/bnode.rdf +16 -0
- data/spec/swap_test/ref/colon-in-uri.n3 +15 -0
- data/spec/swap_test/ref/daml-ex.n3 +103 -0
- data/spec/swap_test/ref/daml-ont.n3 +289 -0
- data/spec/swap_test/ref/djb1a-out.n3 +4 -0
- data/spec/swap_test/ref/dot-dash.n3 +8 -0
- data/spec/swap_test/ref/in-xml-t.n3 +4 -0
- data/spec/swap_test/ref/itemType.n3 +9 -0
- data/spec/swap_test/ref/keywords1.n3 +11 -0
- data/spec/swap_test/ref/keywords2.n3 +11 -0
- data/spec/swap_test/ref/lists-simple-1.rdf +108 -0
- data/spec/swap_test/ref/lists.n3 +43 -0
- data/spec/swap_test/ref/lstring-out.n3 +20 -0
- data/spec/swap_test/ref/n3string.n3 +13 -0
- data/spec/swap_test/ref/no-last-nl.n3 +3 -0
- data/spec/swap_test/ref/numbers.n3 +18 -0
- data/spec/swap_test/ref/path1.n3 +8 -0
- data/spec/swap_test/ref/path2.n3 +39 -0
- data/spec/swap_test/ref/prefix1.rdf +31 -0
- data/spec/swap_test/ref/prefix3.rdf +31 -0
- data/spec/swap_test/ref/rdf-redefine.rdf +11 -0
- data/spec/swap_test/ref/reluri-1.rdf +18 -0
- data/spec/swap_test/ref/strquot.n3 +23 -0
- data/spec/swap_test/ref/strquot_a.n3 +23 -0
- data/spec/swap_test/ref/xml-base3.n3 +5 -0
- data/spec/swap_test/ref/xml-redefine.rdf +20 -0
- data/spec/swap_test/ref/xml-redefine2.rdf +23 -0
- data/spec/swap_test/ref/xml-syntax-basic-serialization.rdf +10 -0
- data/spec/swap_test/ref/xmllit.nt +3 -0
- data/spec/swap_test/regression.n3 +231 -0
- data/spec/swap_test/reluri-1.n3 +10 -0
- data/spec/swap_test/strquot.n3 +23 -0
- data/spec/swap_test/syntax/colon-in-uri.rdf +27 -0
- data/spec/swap_test/syntax/djb1a.n3 +3 -0
- data/spec/swap_test/syntax/dot-dash.n3 +15 -0
- data/spec/swap_test/syntax/equals1.n3 +1 -0
- data/spec/swap_test/syntax/equals2.n3 +1 -0
- data/spec/swap_test/syntax/keywords1.n3 +17 -0
- data/spec/swap_test/syntax/keywords2.n3 +18 -0
- data/spec/swap_test/syntax/lstring.n3 +26 -0
- data/spec/swap_test/syntax/neg-formula-predicate.n3 +1 -0
- data/spec/swap_test/syntax/neg-keywords3.n3 +1 -0
- data/spec/swap_test/syntax/neg-literal-predicate.n3 +1 -0
- data/spec/swap_test/syntax/neg-single-quote.n3 +1 -0
- data/spec/swap_test/syntax/neg-thisadoc.n3 +1 -0
- data/spec/swap_test/syntax/no-last-nl.n3 +2 -0
- data/spec/swap_test/syntax/numbers.n3 +26 -0
- data/spec/swap_test/syntax/path1.n3 +23 -0
- data/spec/swap_test/syntax/path2.n3 +31 -0
- data/spec/swap_test/syntax/qvars1.n3 +19 -0
- data/spec/swap_test/syntax/qvars2.n3 +19 -0
- data/spec/swap_test/syntax/this-quantifiers.n3 +164 -0
- data/spec/swap_test/syntax/this-rules.n3 +43 -0
- data/spec/swap_test/syntax/too-nested.n3 +25 -0
- data/spec/swap_test/syntax/trailing-semicolon.n3 +12 -0
- data/spec/swap_test/syntax/zero-objects.n3 +1 -0
- data/spec/swap_test/syntax/zero-predicates.n3 +3 -0
- data/spec/swap_test/tests-work.txt +25 -0
- data/spec/swap_test/xml-syntax/basic-serialization.n3 +8 -0
- data/spec/swap_test/xml-syntax/in-xml.xml +13 -0
- data/spec/swap_test/xml-syntax/non-ascii-pred.rdf +14 -0
- data/spec/swap_test/xml-syntax/rdf_prefix.n3 +2 -0
- data/spec/swap_test/xml-syntax/xml_prefix.n3 +7 -0
- data/spec/swap_test/xml-syntax/xml_prefix2.n3 +9 -0
- data/spec/swap_test/xml-syntax/xmlbase3.rdf +10 -0
- data/spec/swap_test/xml-syntax/xmllit.rdf +33 -0
- data/spec/triple_spec.rb +90 -46
- data/spec/turtle/README.txt +20 -0
- data/spec/turtle/bad-00.ttl +2 -0
- data/spec/turtle/bad-01.ttl +3 -0
- data/spec/turtle/bad-02.ttl +3 -0
- data/spec/turtle/bad-03.ttl +3 -0
- data/spec/turtle/bad-04.ttl +3 -0
- data/spec/turtle/bad-05.ttl +4 -0
- data/spec/turtle/bad-06.ttl +3 -0
- data/spec/turtle/bad-07.ttl +4 -0
- data/spec/turtle/bad-08.ttl +2 -0
- data/spec/turtle/bad-09.ttl +3 -0
- data/spec/turtle/bad-10.ttl +3 -0
- data/spec/turtle/bad-11.ttl +3 -0
- data/spec/turtle/bad-12.ttl +3 -0
- data/spec/turtle/bad-13.ttl +3 -0
- data/spec/turtle/bad-14.ttl +6 -0
- data/spec/turtle/manifest-bad.ttl +88 -0
- data/spec/turtle/manifest.ttl +215 -0
- data/spec/turtle/rdf-schema.out +126 -0
- data/spec/turtle/rdf-schema.ttl +156 -0
- data/spec/turtle/rdfq-results.out +36 -0
- data/spec/turtle/rdfq-results.ttl +39 -0
- data/spec/turtle/rdfs-namespace.out +131 -0
- data/spec/turtle/rdfs-namespace.ttl +160 -0
- data/spec/turtle/test-00.out +1 -0
- data/spec/turtle/test-00.ttl +2 -0
- data/spec/turtle/test-01.out +3 -0
- data/spec/turtle/test-01.ttl +7 -0
- data/spec/turtle/test-02.out +3 -0
- data/spec/turtle/test-02.ttl +5 -0
- data/spec/turtle/test-03.out +3 -0
- data/spec/turtle/test-03.ttl +5 -0
- data/spec/turtle/test-04.out +2 -0
- data/spec/turtle/test-04.ttl +4 -0
- data/spec/turtle/test-05.out +4 -0
- data/spec/turtle/test-05.ttl +4 -0
- data/spec/turtle/test-06.out +1 -0
- data/spec/turtle/test-06.ttl +3 -0
- data/spec/turtle/test-07.out +5 -0
- data/spec/turtle/test-07.ttl +3 -0
- data/spec/turtle/test-08.out +1 -0
- data/spec/turtle/test-08.ttl +3 -0
- data/spec/turtle/test-09.out +4 -0
- data/spec/turtle/test-09.ttl +10 -0
- data/spec/turtle/test-10.out +5 -0
- data/spec/turtle/test-10.ttl +5 -0
- data/spec/turtle/test-11.out +4 -0
- data/spec/turtle/test-11.ttl +10 -0
- data/spec/turtle/test-12.out +4 -0
- data/spec/turtle/test-12.ttl +9 -0
- data/spec/turtle/test-13.out +2 -0
- data/spec/turtle/test-13.ttl +7 -0
- data/spec/turtle/test-14.out +10000 -0
- data/spec/turtle/test-14.ttl +10002 -0
- data/spec/turtle/test-15.out +10000 -0
- data/spec/turtle/test-15.ttl +3 -0
- data/spec/turtle/test-16.out +10000 -0
- data/spec/turtle/test-16.ttl +10002 -0
- data/spec/turtle/test-17.out +1 -0
- data/spec/turtle/test-17.ttl +6 -0
- data/spec/turtle/test-18.out +2 -0
- data/spec/turtle/test-18.ttl +9 -0
- data/spec/turtle/test-19.out +1 -0
- data/spec/turtle/test-19.ttl +4 -0
- data/spec/turtle/test-20.out +2 -0
- data/spec/turtle/test-20.ttl +6 -0
- data/spec/turtle/test-21.out +3 -0
- data/spec/turtle/test-21.ttl +4 -0
- data/spec/turtle/test-22.out +3 -0
- data/spec/turtle/test-22.ttl +4 -0
- data/spec/turtle/test-23.out +1 -0
- data/spec/turtle/test-23.ttl +3 -0
- data/spec/turtle/test-24.out +2 -0
- data/spec/turtle/test-24.ttl +3 -0
- data/spec/turtle/test-25.out +7 -0
- data/spec/turtle/test-25.ttl +14 -0
- data/spec/turtle/test-26.out +1 -0
- data/spec/turtle/test-26.ttl +4 -0
- data/spec/turtle/test-27.out +1 -0
- data/spec/turtle/test-27.ttl +5 -0
- data/spec/turtle/test-28-out.ttl +6 -0
- data/spec/turtle/test-28.out +22 -0
- data/spec/turtle/test-28.ttl +22 -0
- data/spec/turtle/test-29.out +1 -0
- data/spec/turtle/test-29.ttl +1 -0
- data/spec/turtle/test-30.out +5 -0
- data/spec/turtle/test-30.ttl +12 -0
- data/spec/turtle_spec.rb +64 -0
- data/spec/uriref_spec.rb +74 -34
- data/test/n3_tests/rdflib/n3-writer-teset-26.n3 +31 -0
- data/test/n3_tests/rdflib/n3-writer-teset-26.nt +14 -0
- data/test/rdf_tests/xml-literal-mixed.nt +1 -2
- metadata +278 -39
- data/lib/rdf_context/n3_grammar.rb +0 -2171
- data/test/perf_test/test.rb +0 -11
- data/test/perf_test/tommorris.rdf +0 -2267
data/lib/rdf_context/triple.rb
CHANGED
@@ -12,8 +12,8 @@ module RdfContext
|
|
12
12
|
##
|
13
13
|
# Creates a new triple directly from the intended subject, predicate, and object.
|
14
14
|
#
|
15
|
-
# Any or all of _subject_, _predicate_ or _object_ may be nil, to create a triple
|
16
|
-
# A
|
15
|
+
# Any or all of _subject_, _predicate_ or _object_ may be nil, to create a triple pattern.
|
16
|
+
# A pattern may not be added to a graph.
|
17
17
|
#
|
18
18
|
# ==== Example
|
19
19
|
# Triple.new(BNode.new, URIRef.new("http://xmlns.com/foaf/0.1/knows"), BNode.new) # => results in the creation of a new triple and returns it
|
@@ -21,24 +21,24 @@ module RdfContext
|
|
21
21
|
# @param [URIRef, BNode] subject:: the subject of the triple
|
22
22
|
# @param [URIRef] predicate:: the predicate of the triple
|
23
23
|
# @param [URIRef, BNode, Literal, TypedLiteral] object:: the object of the triple
|
24
|
-
# @return [Triple]::
|
24
|
+
# @return [Triple]:: Generated triple
|
25
25
|
# @raise [Error]:: Checks parameter types and raises if they are incorrect.
|
26
26
|
#
|
27
27
|
# @author Tom Morris
|
28
28
|
def initialize (subject, predicate, object)
|
29
|
-
@subject = self.class.
|
29
|
+
@subject = self.class.coerce_node(subject)
|
30
30
|
@predicate = self.class.coerce_predicate(predicate)
|
31
|
-
@object = self.class.
|
32
|
-
@
|
31
|
+
@object = self.class.coerce_node(object)
|
32
|
+
@pattern = subject.nil? || predicate.nil? || object.nil?
|
33
33
|
end
|
34
34
|
|
35
|
-
def
|
36
|
-
@
|
35
|
+
def is_pattern?
|
36
|
+
@pattern
|
37
37
|
end
|
38
38
|
|
39
39
|
# Serialize Triple to N3
|
40
40
|
def to_n3
|
41
|
-
raise RdfException.new("Can't serialize
|
41
|
+
raise RdfException.new("Can't serialize pattern triple '#{@subject.inspect}, #{@predicate.inspect}, #{@object.inspect}'") if is_pattern?
|
42
42
|
@subject.to_ntriples + " " + @predicate.to_ntriples + " " + @object.to_ntriples + " ."
|
43
43
|
end
|
44
44
|
alias_method :to_ntriples, :to_n3
|
@@ -55,7 +55,7 @@ module RdfContext
|
|
55
55
|
end
|
56
56
|
|
57
57
|
# Two triples are equal if their of their subjects, predicates and objects are equal.
|
58
|
-
# Or self or other is a
|
58
|
+
# Or self or other is a pattern and subject, predicate, object matches
|
59
59
|
def eql? (other)
|
60
60
|
other.is_a?(Triple) &&
|
61
61
|
(other.subject == self.subject || other.subject.nil? || self.subject.nil?) &&
|
@@ -67,13 +67,19 @@ module RdfContext
|
|
67
67
|
|
68
68
|
# Clone triple, keeping references to literals and URIRefs, but cloning BNodes
|
69
69
|
def clone
|
70
|
-
raise RdfException.new("Can't clone
|
70
|
+
raise RdfException.new("Can't clone pattern triple") if is_pattern?
|
71
71
|
s = subject.is_a?(BNode) ? subject.clone : subject
|
72
72
|
p = predicate.is_a?(BNode) ? predicate.clone : predicate
|
73
73
|
o = object.is_a?(BNode) ? object.clone : object
|
74
74
|
Triple.new(subject, predicate, object)
|
75
75
|
end
|
76
76
|
|
77
|
+
# Validate that this triple is legal RDF, not extended for Notation-3
|
78
|
+
def validate_rdf
|
79
|
+
raise InvalidNode, "Triple has illegal RDF subject #{subject.inspect}" unless subject.is_a?(URIRef) || subject.is_a?(BNode)
|
80
|
+
raise InvalidPredicate, "Triple has illegal RDF predicate #{predicate.inspect}" unless predicate.is_a?(URIRef)
|
81
|
+
end
|
82
|
+
|
77
83
|
# For indexes
|
78
84
|
def hash
|
79
85
|
[subject, predicate, object].hash
|
@@ -81,25 +87,6 @@ module RdfContext
|
|
81
87
|
|
82
88
|
protected
|
83
89
|
|
84
|
-
# Coerce a subject to the appropriate RdfContext type.
|
85
|
-
#
|
86
|
-
# @param[URI, URIRef, String] subject:: If a String looks like a URI, a URI is created, otherwise a BNode.
|
87
|
-
# @raise[InvalidSubject]:: If subject can't be intuited.
|
88
|
-
def self.coerce_subject(subject)
|
89
|
-
case subject
|
90
|
-
when Addressable::URI
|
91
|
-
URIRef.new(subject.to_s)
|
92
|
-
when URIRef, BNode
|
93
|
-
subject
|
94
|
-
when nil
|
95
|
-
subject
|
96
|
-
when /^\w+:\/\/\S+/, /^file:\S+/ # does it smell like a URI?
|
97
|
-
URIRef.new(subject)
|
98
|
-
else
|
99
|
-
raise InvalidSubject, "Subject is not of a known class (#{subject.class}: #{subject.inspect})"
|
100
|
-
end
|
101
|
-
end
|
102
|
-
|
103
90
|
# Coerce a predicate to the appropriate RdfContext type.
|
104
91
|
#
|
105
92
|
# @param[URI, URIRef, String] predicate:: If a String looks like a URI, a URI is created
|
@@ -108,7 +95,7 @@ module RdfContext
|
|
108
95
|
case predicate
|
109
96
|
when Addressable::URI
|
110
97
|
URIRef.new(predicate.to_s)
|
111
|
-
when URIRef
|
98
|
+
when URIRef, BNode
|
112
99
|
predicate
|
113
100
|
when String
|
114
101
|
URIRef.new predicate
|
@@ -118,31 +105,29 @@ module RdfContext
|
|
118
105
|
raise InvalidPredicate, "Predicate should be a URI"
|
119
106
|
end
|
120
107
|
rescue ParserException => e
|
121
|
-
raise InvalidPredicate, "
|
108
|
+
raise InvalidPredicate, "#{predicate.class}: #{predicate.inspect} is not a valid predicate"
|
122
109
|
end
|
123
110
|
|
124
|
-
# Coerce a object to the appropriate RdfContext type.
|
111
|
+
# Coerce a node (subject or object) to the appropriate RdfContext type.
|
125
112
|
#
|
126
113
|
# @param[URI, URIRef, String, Integer, Float, BNode, Literal] object:: If a String looks like a URI, a URI is created, otherwise an untyped Literal.
|
127
|
-
# @raise[
|
128
|
-
def self.
|
129
|
-
case
|
114
|
+
# @raise[InvalidNode]:: If node can't be predicate.
|
115
|
+
def self.coerce_node(node)
|
116
|
+
case node
|
130
117
|
when Addressable::URI
|
131
|
-
URIRef.new(
|
118
|
+
URIRef.new(node.to_s)
|
132
119
|
when String
|
133
|
-
if
|
134
|
-
URIRef.new(
|
120
|
+
if node.to_s =~ /^\w+:\/\/\S+/ # does it smell like a URI?
|
121
|
+
URIRef.new(node.to_s)
|
135
122
|
else
|
136
|
-
Literal.untyped(
|
123
|
+
Literal.untyped(node)
|
137
124
|
end
|
138
|
-
when
|
139
|
-
Literal.build_from(
|
140
|
-
when URIRef, BNode, Literal
|
141
|
-
|
142
|
-
when nil
|
143
|
-
object
|
125
|
+
when Numeric, Date, Duration, Time, DateTime
|
126
|
+
Literal.build_from(node)
|
127
|
+
when URIRef, BNode, Literal, Graph, nil
|
128
|
+
node
|
144
129
|
else
|
145
|
-
raise
|
130
|
+
raise InvalidNode, "#{node.class}: #{node.inspect} is not a valid node"
|
146
131
|
end
|
147
132
|
end
|
148
133
|
end
|
data/lib/rdf_context/uriref.rb
CHANGED
@@ -11,24 +11,31 @@ module RdfContext
|
|
11
11
|
# u = URIRef.new("http://example.com")
|
12
12
|
# u = URIRef.new("foo", u) => "http://example.com/foo"
|
13
13
|
#
|
14
|
+
# Last argument may be an options hash to set:
|
15
|
+
# @options[:normalize]:: Normalize URI when transforming to string, defaults to true
|
16
|
+
# @options[:namespace]:: Namespace used to create this URI, useful for to_qname
|
14
17
|
def initialize (*args)
|
18
|
+
options = args.last.is_a?(Hash) ? args.pop : { :normalize => true }
|
19
|
+
@normalize = options[:normalize]
|
20
|
+
@namespace = options[:namespace]
|
21
|
+
|
15
22
|
args.each {|s| test_string(s)}
|
16
23
|
if args.size == 1
|
17
|
-
|
24
|
+
uri = Addressable::URI.parse(args[0].to_s)
|
18
25
|
else
|
19
|
-
|
20
|
-
end
|
21
|
-
if @uri.relative?
|
22
|
-
raise ParserException, "<" + @uri.to_s + "> is a relative URI"
|
26
|
+
uri = Addressable::URI.join(*args.map{|s| s.to_s}.reverse)
|
23
27
|
end
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
+
|
29
|
+
raise ParserException, "<" + uri.to_s + "> is a relative URI" if uri.relative?
|
30
|
+
|
28
31
|
# Unique URI through class hash to ensure that URIRefs can be easily compared
|
29
32
|
@@uri_hash ||= {}
|
30
|
-
@@uri_hash[@
|
31
|
-
|
33
|
+
@uri = @@uri_hash["#{uri}#{@normalize}"] ||= begin
|
34
|
+
# Special case if URI has no path, and the authority ends with a '#'
|
35
|
+
uri = Addressable::URI.parse($1) if @normalize && uri.to_s.match(/^(.*)\#$/)
|
36
|
+
|
37
|
+
@normalize ? uri.normalize : uri
|
38
|
+
end.freeze
|
32
39
|
end
|
33
40
|
|
34
41
|
# Create a URI, either by appending a fragment, or using the input URI
|
@@ -40,7 +47,9 @@ module RdfContext
|
|
40
47
|
# short_name of URI for creating QNames.
|
41
48
|
# "#{base]{#short_name}}" == uri
|
42
49
|
def short_name
|
43
|
-
@short_name ||= if @
|
50
|
+
@short_name ||= if @namespace
|
51
|
+
self.to_s.sub(@namespace.uri.to_s, "")
|
52
|
+
elsif @uri.fragment()
|
44
53
|
@uri.fragment()
|
45
54
|
elsif @uri.path.split("/").last.class == String and @uri.path.split("/").last.length > 0
|
46
55
|
@uri.path.split("/").last
|
@@ -53,14 +62,14 @@ module RdfContext
|
|
53
62
|
# "#{base]{#short_name}}" == uri
|
54
63
|
def base
|
55
64
|
@base ||= begin
|
56
|
-
uri_base =
|
65
|
+
uri_base = self.to_s
|
57
66
|
sn = short_name.to_s
|
58
67
|
uri_base[0, uri_base.length - sn.length]
|
59
68
|
end
|
60
69
|
end
|
61
70
|
|
62
71
|
def eql?(other)
|
63
|
-
|
72
|
+
self.to_s == other.to_s
|
64
73
|
end
|
65
74
|
alias_method :==, :eql?
|
66
75
|
|
@@ -68,24 +77,26 @@ module RdfContext
|
|
68
77
|
def hash; to_s.hash; end
|
69
78
|
|
70
79
|
def to_s
|
71
|
-
@uri.to_s
|
80
|
+
@to_s ||= @uri.to_s
|
72
81
|
end
|
73
82
|
|
74
83
|
def to_n3
|
75
|
-
"<" +
|
84
|
+
"<" + self.to_s + ">"
|
76
85
|
end
|
77
86
|
alias_method :to_ntriples, :to_n3
|
78
87
|
|
79
88
|
# Output URI as QName using URI binding
|
80
89
|
def to_qname(uri_binding = {})
|
81
|
-
|
90
|
+
ns = namespace(uri_binding)
|
91
|
+
sn = self.to_s.sub(ns.uri.to_s, "")
|
92
|
+
"#{ns.prefix}:#{sn}"
|
82
93
|
end
|
83
94
|
|
84
95
|
def namespace(uri_binding = {})
|
85
96
|
@namespace ||= begin
|
86
|
-
|
87
|
-
raise RdfException, "Couldn't find namespace for #{@uri}" unless
|
88
|
-
|
97
|
+
uri = uri_binding.keys.detect {|u| self.to_s.index(u) == 0 }
|
98
|
+
raise RdfException, "Couldn't find namespace for #{@uri}" unless uri
|
99
|
+
uri_binding[uri]
|
89
100
|
end
|
90
101
|
end
|
91
102
|
|
@@ -95,9 +106,10 @@ module RdfContext
|
|
95
106
|
|
96
107
|
# Output URI as resource reference for RDF/XML
|
97
108
|
def xml_args
|
98
|
-
[{"rdf:resource" =>
|
109
|
+
[{"rdf:resource" => self.to_s}]
|
99
110
|
end
|
100
111
|
|
112
|
+
protected
|
101
113
|
def test_string (string)
|
102
114
|
string.to_s.each_byte do |b|
|
103
115
|
if b >= 0 and b <= 31
|
@@ -105,10 +117,5 @@ module RdfContext
|
|
105
117
|
end
|
106
118
|
end
|
107
119
|
end
|
108
|
-
|
109
|
-
# def load_graph
|
110
|
-
# get = Net::HTTP.start(@uri.host, @uri.port) {|http| [:xml, http.get(@uri.path)] }
|
111
|
-
# return RdfContext::RdfXmlParser.new(get[1].body, @uri.to_s).graph if get[0] == :xml
|
112
|
-
# end
|
113
120
|
end
|
114
121
|
end
|
@@ -0,0 +1,59 @@
|
|
1
|
+
require File.join(File.dirname(__FILE__), 'spec_helper')
|
2
|
+
|
3
|
+
describe "AggregateGraph" do
|
4
|
+
before(:all) do
|
5
|
+
@store = MemoryStore.new(@identifier)
|
6
|
+
@graph1 = Graph.new(:store => @store)
|
7
|
+
@graph2 = Graph.new(:store => @store)
|
8
|
+
@graph3 = Graph.new(:store => @store)
|
9
|
+
|
10
|
+
@graph1.parse(%(
|
11
|
+
@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
|
12
|
+
@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
|
13
|
+
@prefix : <http://test/> .
|
14
|
+
:foo a rdfs:Class.
|
15
|
+
:bar :d :c.
|
16
|
+
:a :d :c.
|
17
|
+
), "http://test/")
|
18
|
+
|
19
|
+
@graph2.parse(%(
|
20
|
+
@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
|
21
|
+
@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
|
22
|
+
@prefix : <http://test/> .
|
23
|
+
@prefix log: <http://www.w3.org/2000/10/swap/log#>.
|
24
|
+
:foo a rdfs:Resource.
|
25
|
+
:bar rdfs:isDefinedBy [ a log:Formula ].
|
26
|
+
:a :d :e.
|
27
|
+
), "http://test/")
|
28
|
+
|
29
|
+
@graph3.parse(%(
|
30
|
+
@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
|
31
|
+
@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
|
32
|
+
@prefix log: <http://www.w3.org/2000/10/swap/log#>.
|
33
|
+
@prefix : <http://test/> .
|
34
|
+
<> a log:N3Document.
|
35
|
+
), "http://test/")
|
36
|
+
end
|
37
|
+
|
38
|
+
subject { AggregateGraph.new(@graph1, @graph2, @graph3)}
|
39
|
+
|
40
|
+
it "should return types" do
|
41
|
+
subject.triples(Triple.new(nil, RDF_TYPE, nil)).length.should == 4
|
42
|
+
end
|
43
|
+
|
44
|
+
it "should return subjects" do
|
45
|
+
subject.triples(Triple.new("http://test/bar", nil, nil)).length.should == 2
|
46
|
+
end
|
47
|
+
|
48
|
+
it "should return predicates" do
|
49
|
+
subject.triples(Triple.new(nil, "http://test/d", nil)).length.should == 3
|
50
|
+
end
|
51
|
+
|
52
|
+
it "should have size sum of graphs" do
|
53
|
+
subject.size.should == @graph1.size + @graph2.size + @graph3.size
|
54
|
+
end
|
55
|
+
|
56
|
+
it "should contain a triple" do
|
57
|
+
subject.contains?(Triple.new("http://test/foo", RDF_TYPE, RDFS_NS.Resource)).should be_true
|
58
|
+
end
|
59
|
+
end
|
@@ -56,7 +56,7 @@ describe "ConjunctiveGraph" do
|
|
56
56
|
it "should parse into new context" do
|
57
57
|
n3_string = "<http://example.org/> <http://xmlns.com/foaf/0.1/name> \"Gregg Kellogg\" . "
|
58
58
|
graph = subject.parse(n3_string, "http://foo.bar", :type => :n3)
|
59
|
-
graph.identifier.should == "http://foo.bar"
|
59
|
+
graph.identifier.should == "http://foo.bar/"
|
60
60
|
subject.size.should == 1
|
61
61
|
t = subject.triples.first
|
62
62
|
t.subject.to_s.should == "http://example.org/"
|
data/spec/cwm_spec.rb
ADDED
@@ -0,0 +1,32 @@
|
|
1
|
+
require File.join(File.dirname(__FILE__), 'spec_helper')
|
2
|
+
include RdfContext
|
3
|
+
|
4
|
+
describe "N3 parser" do
|
5
|
+
describe "w3c cwm tests" do
|
6
|
+
require 'rdf_helper'
|
7
|
+
|
8
|
+
def self.test_cases
|
9
|
+
RdfHelper::TestCase.test_cases(CWM_TEST, SWAP_DIR) rescue []
|
10
|
+
end
|
11
|
+
|
12
|
+
# Negative parser tests should raise errors.
|
13
|
+
test_cases.each do |t|
|
14
|
+
#next unless t.about.uri.to_s =~ /rdfms-rdf-names-use/
|
15
|
+
#next unless t.name =~ /11/
|
16
|
+
#puts t.inspect
|
17
|
+
specify "test #{t.name}: " + (t.description || "#{t.inputDocument} against #{t.outputDocument}") do
|
18
|
+
begin
|
19
|
+
t.run_test do |rdf_string, parser|
|
20
|
+
parser.parse(rdf_string, t.about.uri.to_s, :strict => true, :debug => [])
|
21
|
+
end
|
22
|
+
rescue #Spec::Expectations::ExpectationNotMetError => e
|
23
|
+
if t.status == "pending"
|
24
|
+
pending("Formulae not supported") { raise }
|
25
|
+
else
|
26
|
+
raise
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
data/spec/graph_spec.rb
CHANGED
@@ -188,6 +188,43 @@ HERE
|
|
188
188
|
xml.should include("Ralph Swick")
|
189
189
|
xml.should include("Manu Sporny")
|
190
190
|
end
|
191
|
+
|
192
|
+
it "should find bnodes" do
|
193
|
+
subject.bnodes.length.should == 2
|
194
|
+
end
|
195
|
+
|
196
|
+
it "should find predicate bnodes" do
|
197
|
+
subject.allow_n3 = true
|
198
|
+
c = BNode.new("c")
|
199
|
+
subject << Triple.new(URIRef.new("http://foo"), c, Literal.untyped("BNode predicate"))
|
200
|
+
subject.bnodes.length.should == 3
|
201
|
+
subject.bnodes.should include(c)
|
202
|
+
end
|
203
|
+
end
|
204
|
+
|
205
|
+
describe "with namespaces" do
|
206
|
+
subject { Graph.new(:store => ListStore.new) }
|
207
|
+
|
208
|
+
it "should use namespace with trailing slash" do
|
209
|
+
ns = Namespace.new("http://www.example.com/ontologies/test/", "test")
|
210
|
+
subject.bind(ns)
|
211
|
+
subject.add_triple("http://example.com", ns.hasChallenge, "Interesting Title")
|
212
|
+
subject.to_rdfxml.should =~ /<test:hasChallenge/
|
213
|
+
end
|
214
|
+
|
215
|
+
it "should use namespace with trailing #" do
|
216
|
+
ns = Namespace.new("http://www.example.com/ontologies/test#", "test")
|
217
|
+
subject.bind(ns)
|
218
|
+
subject.add_triple("http://example.com", ns.hasChallenge, "Interesting Title")
|
219
|
+
subject.to_rdfxml.should =~ /<test:hasChallenge/
|
220
|
+
end
|
221
|
+
|
222
|
+
it "should use namespace with trailing word" do
|
223
|
+
ns = Namespace.new("http://www.example.com/ontologies/test", "test")
|
224
|
+
subject.bind(ns)
|
225
|
+
subject.add_triple("http://example.com", ns.hasChallenge, "Interesting Title")
|
226
|
+
subject.to_rdfxml.should =~ /<test:hasChallenge/
|
227
|
+
end
|
191
228
|
end
|
192
229
|
|
193
230
|
describe "with triples" do
|
@@ -307,6 +344,41 @@ HERE
|
|
307
344
|
subject.to_rdfxml.should be_equivalent_xml(rdfxml)
|
308
345
|
end
|
309
346
|
end
|
347
|
+
|
348
|
+
describe "rdf:_n sequences" do
|
349
|
+
subject {
|
350
|
+
g = Graph.new(:store => ListStore.new)
|
351
|
+
g.add_triple(@ex.Seq, RDF_TYPE, RDF_NS.Seq)
|
352
|
+
g.add_triple(@ex.Seq, RDF_NS._1, @ex.john)
|
353
|
+
g.add_triple(@ex.Seq, RDF_NS._2, @ex.jane)
|
354
|
+
g.add_triple(@ex.Seq, RDF_NS._3, @ex.rick)
|
355
|
+
g.bind(@ex)
|
356
|
+
g
|
357
|
+
}
|
358
|
+
|
359
|
+
it "should return object list" do
|
360
|
+
subject.seq(@ex.Seq).should == [@ex.john, @ex.jane, @ex.rick]
|
361
|
+
end
|
362
|
+
end
|
363
|
+
|
364
|
+
describe "rdf:first/rdf:rest sequences" do
|
365
|
+
subject {
|
366
|
+
a, b = BNode.new("a"), BNode.new("b"), BNode.new("c")
|
367
|
+
g = Graph.new(:store => ListStore.new)
|
368
|
+
g.add_triple(@ex.List, RDF_NS.first, @ex.john)
|
369
|
+
g.add_triple(@ex.List, RDF_NS.rest, a)
|
370
|
+
g.add_triple(a, RDF_NS.first, @ex.jane)
|
371
|
+
g.add_triple(a, RDF_NS.rest, b)
|
372
|
+
g.add_triple(b, RDF_NS.first, @ex.rick)
|
373
|
+
g.add_triple(b, RDF_NS.rest, RDF_NS.nil)
|
374
|
+
g.bind(@ex)
|
375
|
+
g
|
376
|
+
}
|
377
|
+
|
378
|
+
it "should return object list" do
|
379
|
+
subject.seq(@ex.List).should == [@ex.john, @ex.jane, @ex.rick]
|
380
|
+
end
|
381
|
+
end
|
310
382
|
end
|
311
383
|
|
312
384
|
describe "which are merged" do
|
@@ -335,9 +407,9 @@ HERE
|
|
335
407
|
g.add_triple(BNode.new("a1", @bn_ctx), URIRef.new("http://xmlns.com/foaf/0.1/knows"), BNode.new("a2", @bn_ctx))
|
336
408
|
g.merge!(subject)
|
337
409
|
g.size.should == 2
|
338
|
-
s1, s2 = g.triples.map
|
339
|
-
p1, p2 = g.triples.map
|
340
|
-
o1, o2 = g.triples.map
|
410
|
+
s1, s2 = g.triples.map {|s| s.subject}
|
411
|
+
p1, p2 = g.triples.map {|p| p.predicate}
|
412
|
+
o1, o2 = g.triples.map {|o| o.object}
|
341
413
|
s1.should_not == s2
|
342
414
|
p1.should == p1
|
343
415
|
o1.should_not == o2
|
@@ -380,6 +452,17 @@ HERE
|
|
380
452
|
subject.should == f
|
381
453
|
end
|
382
454
|
|
455
|
+
it "should be true for equivalent graphs with different BNode predicates" do
|
456
|
+
subject.allow_n3 = true
|
457
|
+
subject.add_triple(@ex.a, BNode.new("knows", @bn_ctx), @ex.b)
|
458
|
+
subject.add_triple(@ex.b, BNode.new("knows", @bn_ctx), @ex.a)
|
459
|
+
|
460
|
+
f = Graph.new(:store => s, :identifier => subject.identifier, :allow_n3 => true)
|
461
|
+
f.add_triple(@ex.a, BNode.new("knows", @bn_ctx), @ex.b)
|
462
|
+
f.add_triple(@ex.b, BNode.new("knows", @bn_ctx), @ex.a)
|
463
|
+
subject.should == f
|
464
|
+
end
|
465
|
+
|
383
466
|
it "should be true for graphs with literals" do
|
384
467
|
subject.add_triple(@ex.a, @foaf.knows, Literal.untyped("foo"))
|
385
468
|
|
@@ -390,4 +473,32 @@ HERE
|
|
390
473
|
end
|
391
474
|
end
|
392
475
|
end
|
476
|
+
|
477
|
+
describe "Bnode Permutation matching" do
|
478
|
+
{
|
479
|
+
"a1" => %w(aA),
|
480
|
+
"a1b1" => %w(aAbB aBbA),
|
481
|
+
"a2b1" => %w(aAbB),
|
482
|
+
"a2b2c1" => %w(aAbBcC aBbAcC),
|
483
|
+
"a2b2c3d3e1f4" => %w(
|
484
|
+
aAbBcCdDeEfF
|
485
|
+
aBbAcCdDeEfF
|
486
|
+
aAbBcDdCeEfF
|
487
|
+
aBbAcDdCeEfF
|
488
|
+
)
|
489
|
+
}.each_pair do |list, perms|
|
490
|
+
it "should permute #{list} as #{perms.to_sentence}" do
|
491
|
+
h_source = list.scan(/\w\d/).inject({}) {|hash, ad| hash[ad[0,1]] = ad[1,1]; hash}
|
492
|
+
h_dest = list.upcase.scan(/\w\d/).inject({}) {|hash, ad| hash[ad[0,1]] = ad[1,1]; hash}
|
493
|
+
subject.send(:bnode_permutations, h_source, h_dest) do |hash|
|
494
|
+
perm = ""
|
495
|
+
#puts hash.inspect
|
496
|
+
hash.keys.sort.each {|k| perm << "#{k}#{hash[k]}"}
|
497
|
+
perms.should include(perm)
|
498
|
+
perms -= [perm]
|
499
|
+
end
|
500
|
+
perms.should be_empty
|
501
|
+
end
|
502
|
+
end
|
503
|
+
end
|
393
504
|
end
|