roadforest 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (71) hide show
  1. data/examples/file-management.rb +98 -0
  2. data/lib/roadforest/application/dispatcher.rb +54 -0
  3. data/lib/roadforest/application/parameters.rb +39 -0
  4. data/lib/roadforest/application/path-provider.rb +18 -0
  5. data/lib/roadforest/application/route-adapter.rb +24 -0
  6. data/lib/roadforest/application/services-host.rb +10 -0
  7. data/lib/roadforest/application.rb +42 -0
  8. data/lib/roadforest/blob-model.rb +56 -0
  9. data/lib/roadforest/content-handling/engine.rb +113 -0
  10. data/lib/roadforest/content-handling/media-type.rb +222 -0
  11. data/lib/roadforest/content-handling/type-handlers/jsonld.rb +172 -0
  12. data/lib/roadforest/http/adapters/excon.rb +47 -0
  13. data/lib/roadforest/http/graph-response.rb +20 -0
  14. data/lib/roadforest/http/graph-transfer.rb +112 -0
  15. data/lib/roadforest/http/message.rb +91 -0
  16. data/lib/roadforest/model.rb +151 -0
  17. data/lib/roadforest/models.rb +2 -0
  18. data/lib/roadforest/rdf/context-fascade.rb +25 -0
  19. data/lib/roadforest/rdf/document.rb +23 -0
  20. data/lib/roadforest/rdf/focus-list.rb +19 -0
  21. data/lib/roadforest/rdf/focus-wrapping.rb +30 -0
  22. data/lib/roadforest/rdf/graph-copier.rb +16 -0
  23. data/lib/roadforest/rdf/graph-focus.rb +95 -0
  24. data/lib/roadforest/rdf/graph-reading.rb +145 -0
  25. data/lib/roadforest/rdf/graph-store.rb +217 -0
  26. data/lib/roadforest/rdf/investigation.rb +90 -0
  27. data/lib/roadforest/rdf/normalization.rb +150 -0
  28. data/lib/roadforest/rdf/parcel.rb +47 -0
  29. data/lib/roadforest/rdf/post-focus.rb +35 -0
  30. data/lib/roadforest/rdf/resource-pattern.rb +60 -0
  31. data/lib/roadforest/rdf/resource-query.rb +58 -0
  32. data/lib/roadforest/rdf/source-rigor/credence/any.rb +9 -0
  33. data/lib/roadforest/rdf/source-rigor/credence/none-if-role-absent.rb +19 -0
  34. data/lib/roadforest/rdf/source-rigor/credence/role-if-available.rb +19 -0
  35. data/lib/roadforest/rdf/source-rigor/credence-annealer.rb +22 -0
  36. data/lib/roadforest/rdf/source-rigor/credence.rb +29 -0
  37. data/lib/roadforest/rdf/source-rigor/http-investigator.rb +20 -0
  38. data/lib/roadforest/rdf/source-rigor/investigator.rb +17 -0
  39. data/lib/roadforest/rdf/source-rigor/null-investigator.rb +10 -0
  40. data/lib/roadforest/rdf/source-rigor.rb +44 -0
  41. data/lib/roadforest/rdf/update-focus.rb +73 -0
  42. data/lib/roadforest/rdf/vocabulary.rb +11 -0
  43. data/lib/roadforest/rdf.rb +6 -0
  44. data/lib/roadforest/remote-host.rb +96 -0
  45. data/lib/roadforest/resource/handlers.rb +43 -0
  46. data/lib/roadforest/resource/http/form-parsing.rb +81 -0
  47. data/lib/roadforest/resource/rdf/leaf-item.rb +21 -0
  48. data/lib/roadforest/resource/rdf/list.rb +19 -0
  49. data/lib/roadforest/resource/rdf/parent-item.rb +26 -0
  50. data/lib/roadforest/resource/rdf/read-only.rb +100 -0
  51. data/lib/roadforest/resource/rdf.rb +4 -0
  52. data/lib/roadforest/resource/role/has-children.rb +22 -0
  53. data/lib/roadforest/resource/role/writable.rb +43 -0
  54. data/lib/roadforest/server.rb +3 -0
  55. data/lib/roadforest/test-support/dispatcher-facade.rb +77 -0
  56. data/lib/roadforest/test-support/http-client.rb +151 -0
  57. data/lib/roadforest/test-support/matchers.rb +67 -0
  58. data/lib/roadforest/test-support/remote-host.rb +23 -0
  59. data/lib/roadforest/test-support/trace-formatter.rb +140 -0
  60. data/lib/roadforest/test-support.rb +2 -0
  61. data/lib/roadforest/utility/class-registry.rb +49 -0
  62. data/lib/roadforest.rb +2 -0
  63. data/spec/client.rb +152 -0
  64. data/spec/credence-annealer.rb +44 -0
  65. data/spec/graph-copier.rb +87 -0
  66. data/spec/graph-store.rb +142 -0
  67. data/spec/media-types.rb +14 -0
  68. data/spec/rdf-parcel.rb +158 -0
  69. data/spec/update-focus.rb +117 -0
  70. data/spec_support/gem_test_suite.rb +0 -0
  71. metadata +241 -0
@@ -0,0 +1,95 @@
1
+ require 'rdf'
2
+ require 'roadforest/rdf/context-fascade'
3
+ require 'roadforest/rdf/focus-wrapping'
4
+ require 'roadforest/rdf/graph-reading'
5
+
6
+ module RoadForest::RDF
7
+ class GraphCollection
8
+ include Enumerable
9
+ end
10
+
11
+ class MultivaluedProperty < GraphCollection
12
+ attr_reader :graph, :subject, :property
13
+ def initialize(graph, subject, property)
14
+ @graph, @subject, @propery = graph, subject, property
15
+ end
16
+
17
+ def values
18
+ query_value(graph, subject, property)
19
+ end
20
+
21
+ def each
22
+ if block_given?
23
+ other
24
+ values.each do |value|
25
+ yield unwrap_value(value)
26
+ end
27
+ else
28
+ values.each
29
+ end
30
+ end
31
+
32
+ def add(value)
33
+ add_statement(subject, property, value)
34
+ end
35
+ end
36
+
37
+ module GraphWriting
38
+ def normalize_triple(property, value, extra=nil)
39
+ if not extra.nil?
40
+ property = [property, value]
41
+ value = extra
42
+ end
43
+ return normalize_property(property), normalize_term(value)
44
+ end
45
+
46
+ def set(property, value, extra=nil)
47
+ property, value = normalize_triple(property, value, extra)
48
+
49
+ delete(property)
50
+ add(property, value)
51
+ return value
52
+ end
53
+ alias_method :[]=, :set
54
+
55
+ def add(property, value, extra=nil)
56
+ property, value = normalize_triple(property, value, extra)
57
+
58
+ target_graph.insert([subject, property, value])
59
+ return value
60
+ end
61
+
62
+ def delete(property, extra=nil)
63
+ target_graph.delete([subject, normalize_property(property, extra), :value])
64
+ end
65
+
66
+ def set_node(property, url=nil)
67
+ node = wrap_node(set(property, normalize_resource(url) || RDF::Node.new))
68
+ yield node if block_given?
69
+ node
70
+ end
71
+ alias node_at set_node
72
+
73
+ def add_node(property, url=nil)
74
+ node = wrap_node(add(property, normalize_resource(url) || RDF::Node.new))
75
+ yield node if block_given?
76
+ node
77
+ end
78
+
79
+ def add_list(property, extra=nil)
80
+ list = ::RDF::List.new(nil, target_graph)
81
+ target_graph.insert([subject, normalize_property(property, extra), list.subject])
82
+ yield list if block_given?
83
+ return list
84
+ end
85
+ end
86
+
87
+ class GraphFocus < GraphReading
88
+ include GraphWriting
89
+
90
+ def target_graph
91
+ graph
92
+ end
93
+
94
+ end
95
+ end
@@ -0,0 +1,145 @@
1
+ require 'roadforest/rdf/focus-list'
2
+ require 'roadforest/rdf/normalization'
3
+ require 'roadforest/rdf/focus-wrapping'
4
+ require 'roadforest/rdf/resource-query'
5
+
6
+ module RoadForest::RDF
7
+ class GraphReading
8
+ include Normalization
9
+ include FocusWrapping
10
+
11
+ attr_accessor :graph, :subject, :root_url, :source_rigor
12
+ alias rdf subject
13
+
14
+ def initialize(subject = nil, graph = nil, rigor = nil)
15
+ @graph = nil
16
+ @subject = nil
17
+ @root_url = nil
18
+ @source_rigor = nil
19
+ self.subject = subject unless subject.nil?
20
+ self.graph = graph unless graph.nil?
21
+ self.source_rigor = rigor unless rigor.nil?
22
+ end
23
+
24
+ def inspect
25
+ "#<#{self.class.name}:0x#{"%x" % object_id} (#{subject.to_s}) #{forward_properties.inspect}>"
26
+ end
27
+
28
+ def dup
29
+ other = self.class.new
30
+ other.graph = graph
31
+ other.subject = subject
32
+ other.root_url = root_url
33
+ other.source_rigor = source_rigor
34
+ other
35
+ end
36
+
37
+ def to_context
38
+ normalize_context(subject)
39
+ end
40
+
41
+ def root_url=(*value) #XXX curies?
42
+ @root_url = normalize_resource(value)
43
+ end
44
+
45
+ def subject=(*value)
46
+ @subject = normalize_resource(value)
47
+ case @subject
48
+ when ::RDF::URI
49
+ @root_url ||= @subject
50
+ end
51
+ end
52
+
53
+ def build_query
54
+ ResourceQuery.new([], {}) do |query|
55
+ query.subject_context = @root_url
56
+ query.source_rigor = @source_rigor
57
+ yield query
58
+ end
59
+ end
60
+
61
+ def forward_properties
62
+ query_properties( build_query{|q| q.pattern([ normalize_resource(subject), :property, :value ])} )
63
+ end
64
+
65
+ def reverse_properties
66
+ query_properties( build_query{|q| q.pattern([ :value, :property, normalize_resource(subject)])} )
67
+ end
68
+
69
+ def get(prefix, property = nil)
70
+ return single_or_enum(forward_query_value( prefix, property))
71
+ end
72
+ alias_method :[], :get
73
+
74
+ def first(prefix, property = nil)
75
+ return forward_query_value( prefix, property ).first
76
+ end
77
+
78
+ def all(prefix, property = nil)
79
+ return forward_query_value( prefix, property )
80
+ end
81
+
82
+ #XXX Maybe rev should return a decorator, so it looks like:
83
+ #focus.rev.get(...) or focus.rev.all(...)
84
+ def rev(prefix, property = nil)
85
+ return single_or_enum(reverse_query_value( prefix, property))
86
+ end
87
+
88
+ def rev_first(prefix, property = nil)
89
+ return reverse_query_value(prefix, property).first
90
+ end
91
+
92
+ def rev_all(prefix, property = nil)
93
+ return reverse_query_value(prefix, property)
94
+ end
95
+
96
+ def as_list
97
+ graph = ContextFascade.new(@graph, @root_url, @source_rigor)
98
+ list = FocusList.new(@subject, graph)
99
+ list.base_node = self
100
+ list.source_rigor = source_rigor
101
+ list
102
+ end
103
+
104
+ protected
105
+
106
+ def reverse_query_value(prefix, property=nil)
107
+ query_value(build_query{|q|
108
+ q.pattern([ :value, normalize_property(prefix, property), normalize_resource(subject)])
109
+ })
110
+ end
111
+
112
+ def forward_query_value(prefix, property=nil)
113
+ query_value(build_query{|q|
114
+ q.pattern([ normalize_resource(subject), normalize_property(prefix, property), :value])
115
+ })
116
+ end
117
+
118
+ def query_value(query)
119
+ solutions = query.execute(graph)
120
+ solutions.map do |solution|
121
+ unwrap_value(solution.value)
122
+ end
123
+ end
124
+ def single_or_enum(values)
125
+ case values.length
126
+ when 0
127
+ return nil
128
+ when 1
129
+ return values.first
130
+ else
131
+ return values.enum_for(:each)
132
+ end
133
+ end
134
+
135
+ def query_properties(query)
136
+ Hash[query.execute(graph).map do |solution|
137
+ prop = solution.property
138
+ if qname = prop.qname
139
+ prop = qname
140
+ end
141
+ [prop, solution.value]
142
+ end]
143
+ end
144
+ end
145
+ end
@@ -0,0 +1,217 @@
1
+ require 'rdf'
2
+ require 'roadforest/rdf/graph-focus'
3
+ require 'roadforest/rdf/vocabulary'
4
+ require 'roadforest/rdf/normalization'
5
+
6
+ require 'roadforest/rdf/resource-query'
7
+ require 'roadforest/rdf/resource-pattern'
8
+
9
+ module RoadForest::RDF
10
+ class GraphStore
11
+ include Normalization
12
+
13
+ #The interface supported by ::RDF::Graph
14
+ include ::RDF::Countable
15
+ include ::RDF::Durable
16
+ include ::RDF::Enumerable
17
+ include ::RDF::Mutable
18
+ include ::RDF::Queryable
19
+ include ::RDF::Resource
20
+
21
+ attr_reader :repository, :current_impulse, :local_context_node
22
+ attr_accessor :debug_io
23
+
24
+ def initialize(repo = nil)
25
+ @repository = repo || RDF::Repository.new
26
+ @local_context_node = RDF::Node.new(:local)
27
+ @debug_io = nil
28
+ next_impulse
29
+ yield self if block_given?
30
+ end
31
+
32
+ def next_impulse
33
+ return if !@current_impulse.nil? and raw_quiet_impulse?
34
+ #mark ended?
35
+ #chain impulses?
36
+ @current_impulse = RDF::Node.new
37
+ repository.insert(normalize_statement(@current_impulse, [:rdf, 'type'], [:rf, 'Impulse'], nil))
38
+ repository.insert(normalize_statement(@current_impulse, [:rf, 'begunAt'], Time.now, nil))
39
+ end
40
+
41
+ def quiet_impulse?
42
+ raw_quiet_impulse?
43
+ end
44
+
45
+ def raw_quiet_impulse?
46
+ repository.query([nil, nil, @current_impulse, false]).to_a.empty?
47
+ end
48
+
49
+ #repo cleanup - expired graphs
50
+
51
+ def reader_for(content_type, repository)
52
+ RDF::Reader.for(content_type)
53
+ end
54
+
55
+ def debug(message)
56
+ return if @debug_io.nil?
57
+ @debug_io.puts(message)
58
+ end
59
+
60
+ def repository_dump(format = :turtle)
61
+ repository.dump(format)
62
+ end
63
+ alias graph_dump repository_dump
64
+
65
+ def delete_statements(pattern)
66
+ repository.delete(pattern)
67
+ end
68
+
69
+ def named_graph(context)
70
+ ::RDF::Graph.new(context, :data => repository)
71
+ end
72
+
73
+ def named_list(context, values = nil)
74
+ ::RDF::List.new(nil, named_graph(context), values)
75
+ end
76
+
77
+ def create_list(values = nil)
78
+ named_list(local_context_node, values)
79
+ end
80
+
81
+ def insert_document(document)
82
+ #puts; puts "#{__FILE__}:#{__LINE__} => #{(document).inspect}"
83
+ #puts document.body_string
84
+ reader = RDF::Reader.for(:content_type => document.content_type) do
85
+ sample = document.body.read(1000)
86
+ document.body.rewind
87
+ sample
88
+ end.new(document.body, :base_uri => document.root_url) #consider :processor_graph
89
+ insert_reader(document.source, reader)
90
+ end
91
+
92
+ def insert_reader(context, reader)
93
+ #puts; puts "#{__FILE__}:#{__LINE__} => #{(context).inspect}"
94
+ context = normalize_context(context)
95
+ delete_statements(:context => context)
96
+ reader.each_statement do |statement|
97
+ statement.context = context
98
+ record_statement(statement)
99
+ end
100
+ #puts; puts "#{__FILE__}:#{__LINE__} => \n#{(graph_dump(:nquads))}"
101
+ end
102
+
103
+ def insert_graph(context, graph)
104
+ context = normalize_context(context)
105
+ delete_statements(:context => context)
106
+ graph.each_statement do |statement|
107
+ statement.context = context
108
+ record_statement(statement)
109
+ end
110
+ end
111
+
112
+ def add_statement(*args)
113
+ case args.length
114
+ when 1
115
+ subject, predicate, object, context = *args.first
116
+ when 2
117
+ triple, context = *args
118
+ subject, predicate, object = *triple
119
+ when 3
120
+ subject, predicate, object = *args
121
+ context = nil
122
+ when 4
123
+ subject, predicate, object, context = *args
124
+ else
125
+ raise ArgumentError, "insert_statement needs some variation of subject, predicate, object, [context]"
126
+ end
127
+ context ||= local_context_node
128
+
129
+ record_statement(normalize_statement(subject, predicate, object, context))
130
+ end
131
+
132
+ def insert_statement(statement)
133
+ repository.insert(statement)
134
+
135
+ repository.delete([statement.context, expand_curie([:rf, "impulse"]), nil])
136
+ repository.insert(normalize_statement(statement.context, [:rf, "impulse"], current_impulse, nil))
137
+ end
138
+ alias record_statement insert_statement
139
+
140
+ def delete_statement(statement)
141
+ repository.query(statement) do |statement|
142
+ next if statement.context.nil?
143
+ repository.delete(statement)
144
+ end
145
+ end
146
+
147
+ def replace(original, statement)
148
+ unless original == statement
149
+ repository.delete(original)
150
+ repository.insert(statement)
151
+ end
152
+ end
153
+
154
+ def each_statement(context=nil, &block)
155
+ query = {}
156
+ unless context.nil?
157
+ query[:context] = context
158
+ end
159
+
160
+ @repository.query(query) do |statement|
161
+ yield statement
162
+ end
163
+ end
164
+
165
+ def durable?
166
+ @repository.durable?
167
+ end
168
+
169
+ #XXX Credence? Default context?
170
+ def each(&block)
171
+ if @repository.respond_to?(:query)
172
+ @repository.query(:context => false, &block)
173
+ elsif @repository.respond_to?(:each)
174
+ @repository.each(&block)
175
+ else
176
+ @repository.to_a.each(&block)
177
+ end
178
+ end
179
+
180
+ #XXX Needed, maybe, if we need to handle constant patterns
181
+ #def include?(statement)
182
+ #end
183
+
184
+ def context_variable
185
+ @context_variable ||= RDF::Query::Variable.new(:context)
186
+ end
187
+
188
+ def query_execute(query, &block)
189
+ #XXX Weird edge case of GM getting queried with a vanilla RDF::Query...
190
+ #needs tests, thought
191
+ query = ResourceQuery.from(query)
192
+ query.execute(self).filter do |solution|
193
+ solution.respond_to?(:context) and not solution.context.nil?
194
+ end.each(&block)
195
+ end
196
+
197
+ def query_pattern(pattern, &block)
198
+ case pattern
199
+ when ResourcePattern
200
+ pattern.execute(@repository, {}, :context_roles => {:local => local_context_node}) do |statement|
201
+ next if statement.context.nil?
202
+ yield statement if block_given?
203
+ end
204
+ else
205
+ pattern.execute(@repository, {}) do |statement|
206
+ next if statement.context.nil?
207
+ yield statement if block_given?
208
+ end
209
+ end
210
+ end
211
+
212
+ def unnamed_graph
213
+ ::RDF::Graph.new(nil, :data => @repository)
214
+ end
215
+
216
+ end
217
+ end
@@ -0,0 +1,90 @@
1
+ require 'roadforest/rdf'
2
+
3
+ module RoadForest::RDF
4
+ class Investigation
5
+ attr_accessor :context_roles, :queryable, :results, :source_rigor
6
+
7
+ def initialize
8
+ @results = []
9
+ end
10
+
11
+ def http_client
12
+ queryable.http_client
13
+ end
14
+
15
+ def found_results?
16
+ !@results.nil?
17
+ end
18
+
19
+ def investigators
20
+ source_rigor.investigators
21
+ end
22
+
23
+ def credence_policies
24
+ source_rigor.credence_policies
25
+ end
26
+
27
+ def make_request(method, url, graph=nil)
28
+ source_rigor.graph_transfer.make_request(method, url, graph)
29
+ end
30
+
31
+
32
+ def insert_graph(context, graph)
33
+ queryable.insert_graph(context, graph)
34
+ end
35
+
36
+ def result
37
+ investigators.each do |investigator|
38
+ self.results = []
39
+ yield(results)
40
+
41
+ contexts = result_contexts
42
+
43
+ catch :not_credible do
44
+ credence_policies.each do |policy|
45
+ contexts = policy.credible(contexts, self)
46
+ if contexts.empty?
47
+ throw :not_credible
48
+ end
49
+ end
50
+ return results_for_context(contexts.first)
51
+ end
52
+
53
+ self.results = nil
54
+ investigator.pursue(self)
55
+
56
+ if found_results?
57
+ return results
58
+ end
59
+ end
60
+ raise NoCredibleResults
61
+ end
62
+
63
+ def result_contexts
64
+ (results.map(&:context) +
65
+ context_roles.values.find_all do |context|
66
+ not context_metadata(context).empty?
67
+ end).uniq
68
+ end
69
+
70
+ def context_metadata(context)
71
+ query = RDF::Query.new do |query|
72
+ query.pattern [context, :property, :value]
73
+ end
74
+ query.execute(queryable.unnamed_graph).select(:property, :value)
75
+ end
76
+
77
+ def results_for_context(context)
78
+ results.find_all{|item| item.context == context}
79
+ end
80
+
81
+ #XXX Do we need the nil result if context_metadata is empty?
82
+ def empty_for_context(context)
83
+ if context_metadata(context).empty? #We've never checked
84
+ nil
85
+ else
86
+ empty_result
87
+ end
88
+ end
89
+ end
90
+ end
@@ -0,0 +1,150 @@
1
+ require 'rdf'
2
+
3
+ module RoadForest::RDF
4
+ module Normalization
5
+ Vocabs = {}
6
+ Vocabs["rdf"] = RDF
7
+
8
+ def normalize_statement(subject, predicate, object, context)
9
+ subject = normalize_resource(subject) || RDF::Node.new
10
+ predicate = normalize_uri(predicate)
11
+ object = normalize_term(object) || RDF::Node.new
12
+ context = normalize_resource(context)
13
+
14
+ RDF::Statement.new(subject, predicate, object, :context => context)
15
+ end
16
+
17
+ def normalize_tuple(tuple)
18
+ subject, predicate, object, context = *tuple
19
+ [ normalize_resource(subject) || RDF::Node.new, normalize_uri(predicate), normalize_term(object) || RDF::Node.new, normalize_resource(context) ]
20
+ end
21
+
22
+ def normalize_resource(from)
23
+ from = expand_curie(from)
24
+ case from
25
+ when nil
26
+ when RDF::Resource
27
+ when /^_:/
28
+ from = RDF::Resource.new(from)
29
+ when String, RDF::URI, Addressable::URI
30
+ from = interned_uri(from)
31
+ when Symbol
32
+ from = RDF::Node.new(from)
33
+ else
34
+ from = RDF::Resource.new(from)
35
+ end
36
+ return from
37
+ end
38
+
39
+ def normalize_context(from)
40
+ case from
41
+ when Array
42
+ from = expand_curie(from)
43
+ when RDF::URI, Addressable::URI, String
44
+ from = uri(from)
45
+ else
46
+ return nil
47
+ end
48
+ from.fragment = nil
49
+ return RDF::URI.intern(from.to_s)
50
+ end
51
+
52
+ def normalize_uri(from)
53
+ from = expand_curie(from)
54
+ case from
55
+ when nil
56
+ when RDF::URI
57
+ else
58
+ from = interned_uri(from)
59
+ end
60
+ return from
61
+ end
62
+
63
+ def normalize_term(object)
64
+ if Array === object
65
+ RDF::Resource.new(expand_curie(object))
66
+ else
67
+ object
68
+ end
69
+ end
70
+
71
+ def literal(object)
72
+ RDF::Literal.new(object)
73
+ end
74
+
75
+ def expand_curie_pair(prefix, property)
76
+ vocab = Vocabs.fetch(prefix) do
77
+ vocab = RDF::Vocabulary.find do |vocab|
78
+ vocab.__prefix__.to_s == prefix
79
+ end
80
+ #p k => vocab #ok
81
+ if vocab.nil?
82
+ raise "Don't know a vocabulary for prefix #{prefix.inspect} in CURIE #{prefix}:#{property}"
83
+ end
84
+ Vocabs[prefix] = vocab
85
+ vocab
86
+ end
87
+ vocab[property]
88
+ end
89
+
90
+ def expand_curie(from)
91
+ case from
92
+ when Array
93
+ case from.length
94
+ when 2
95
+ prefix, property = *from
96
+ return interned_uri(expand_curie_pair(prefix.to_s, property.to_s))
97
+ when 1
98
+ return expand_curie(from.first)
99
+ else
100
+ return from
101
+ end
102
+ else
103
+ return from
104
+ end
105
+ end
106
+
107
+ def normalize_property(prefix, property = nil)
108
+ if property.nil?
109
+ property = prefix
110
+
111
+ case property
112
+ when Array
113
+ normalize_property(*property)
114
+ when String
115
+ RDF::URI.intern(property)
116
+ else
117
+ property
118
+ end
119
+ else
120
+ expand_curie([prefix, property])
121
+ end
122
+ end
123
+
124
+ def root_url
125
+ nil
126
+ end
127
+
128
+ def interned_uri(value)
129
+
130
+ RDF::URI.intern(uri(value))
131
+ end
132
+
133
+ def uri(value)
134
+ if root_url
135
+ value = root_url.join(value)
136
+ else
137
+ value = RDF::URI.new(value)
138
+ end
139
+
140
+ if !value.query.nil? and value.query.empty?
141
+ value.query = nil
142
+ end
143
+ value.validate!
144
+ value.canonicalize!
145
+
146
+ value
147
+ end
148
+ end
149
+
150
+ end