roadforest 0.1 → 0.5

Sign up to get free protection for your applications and to get access to all the features.
Files changed (120) hide show
  1. checksums.yaml +4 -4
  2. data/examples/file-management.rb +12 -13
  3. data/lib/roadforest-client.rb +3 -0
  4. data/lib/roadforest-common.rb +2 -0
  5. data/lib/roadforest-server.rb +7 -0
  6. data/lib/roadforest-testing.rb +1 -0
  7. data/lib/roadforest/application.rb +9 -7
  8. data/lib/roadforest/application/dispatcher.rb +39 -63
  9. data/lib/roadforest/application/parameters.rb +1 -1
  10. data/lib/roadforest/application/path-provider.rb +2 -2
  11. data/lib/roadforest/application/route-adapter.rb +130 -18
  12. data/lib/roadforest/application/services-host.rb +0 -4
  13. data/lib/roadforest/augment/affordance.rb +78 -0
  14. data/lib/roadforest/augment/augmentation.rb +97 -0
  15. data/lib/roadforest/augment/augmenter.rb +54 -0
  16. data/lib/roadforest/augmentations.rb +1 -0
  17. data/lib/roadforest/content-handling.rb +1 -0
  18. data/lib/roadforest/content-handling/common-engines.rb +67 -0
  19. data/lib/roadforest/content-handling/engine.rb +2 -14
  20. data/lib/roadforest/content-handling/handler-wrap.rb +29 -31
  21. data/lib/roadforest/content-handling/media-type.rb +6 -0
  22. data/lib/roadforest/{rdf.rb → graph.rb} +1 -1
  23. data/lib/roadforest/{rdf → graph}/access-manager.rb +12 -74
  24. data/lib/roadforest/{rdf → graph}/document.rb +1 -1
  25. data/lib/roadforest/{rdf → graph}/etagging.rb +2 -2
  26. data/lib/roadforest/{rdf → graph}/focus-list.rb +1 -9
  27. data/lib/roadforest/{rdf → graph}/graph-copier.rb +2 -2
  28. data/lib/roadforest/{rdf → graph}/graph-focus.rb +5 -7
  29. data/lib/roadforest/{rdf → graph}/normalization.rb +1 -1
  30. data/lib/roadforest/{rdf → graph}/post-focus.rb +2 -3
  31. data/lib/roadforest/graph/vocabulary.rb +96 -0
  32. data/lib/roadforest/http/graph-transfer.rb +2 -2
  33. data/lib/roadforest/interface/application.rb +145 -0
  34. data/lib/roadforest/interface/blob.rb +38 -0
  35. data/lib/roadforest/interface/rdf.rb +77 -0
  36. data/lib/roadforest/interfaces.rb +2 -0
  37. data/lib/roadforest/remote-host.rb +17 -17
  38. data/lib/roadforest/resource.rb +4 -0
  39. data/lib/roadforest/resource/{rdf/leaf-item.rb → leaf-item.rb} +1 -1
  40. data/lib/roadforest/resource/{rdf/list.rb → list.rb} +1 -1
  41. data/lib/roadforest/resource/{rdf/parent-item.rb → parent-item.rb} +1 -1
  42. data/lib/roadforest/resource/{rdf/read-only.rb → read-only.rb} +18 -18
  43. data/lib/roadforest/resource/role/has-children.rb +1 -1
  44. data/lib/roadforest/resource/role/writable.rb +2 -2
  45. data/lib/roadforest/server.rb +1 -1
  46. data/lib/roadforest/source-rigor.rb +9 -0
  47. data/lib/roadforest/{rdf/source-rigor → source-rigor}/credence-annealer.rb +2 -2
  48. data/lib/roadforest/{rdf/source-rigor → source-rigor}/credence.rb +5 -5
  49. data/lib/roadforest/{rdf/source-rigor → source-rigor}/credence/any.rb +1 -1
  50. data/lib/roadforest/{rdf/source-rigor → source-rigor}/credence/none-if-role-absent.rb +1 -1
  51. data/lib/roadforest/{rdf/source-rigor → source-rigor}/credence/role-if-available.rb +1 -1
  52. data/lib/roadforest/source-rigor/engine.rb +45 -0
  53. data/lib/roadforest/{rdf → source-rigor}/graph-store.rb +9 -9
  54. data/lib/roadforest/{rdf/source-rigor → source-rigor}/http-investigator.rb +2 -2
  55. data/lib/roadforest/{rdf → source-rigor}/investigation.rb +2 -2
  56. data/lib/roadforest/{rdf/source-rigor → source-rigor}/investigator.rb +3 -3
  57. data/lib/roadforest/{rdf/source-rigor → source-rigor}/null-investigator.rb +3 -2
  58. data/lib/roadforest/{rdf → source-rigor}/parcel.rb +5 -5
  59. data/lib/roadforest/{rdf → source-rigor}/resource-pattern.rb +6 -6
  60. data/lib/roadforest/{rdf → source-rigor}/resource-query.rb +2 -2
  61. data/lib/roadforest/source-rigor/rigorous-access.rb +101 -0
  62. data/lib/roadforest/templates/affordance-doc.haml +23 -0
  63. data/lib/roadforest/templates/affordance-property-values.haml +13 -0
  64. data/lib/roadforest/templates/affordance-subject.haml +9 -0
  65. data/lib/roadforest/templates/affordance-uri-object.haml +2 -0
  66. data/lib/roadforest/templates/base/{property_value.haml → property-value.haml} +0 -0
  67. data/lib/roadforest/templates/base/{property_values.haml → property-values.haml} +0 -0
  68. data/lib/roadforest/templates/distiller/{property_value.haml → property-value.haml} +0 -0
  69. data/lib/roadforest/templates/distiller/{property_values.haml → property-values.haml} +0 -0
  70. data/lib/roadforest/templates/min/{property_values.haml → property-values.haml} +0 -0
  71. data/lib/roadforest/templates/rdfpost-curie.haml +6 -0
  72. data/lib/roadforest/test-support/dispatcher-facade.rb +2 -0
  73. data/lib/roadforest/test-support/matchers.rb +169 -5
  74. data/lib/roadforest/test-support/remote-host.rb +2 -2
  75. data/lib/roadforest/type-handlers/handler.rb +74 -0
  76. data/lib/roadforest/type-handlers/jsonld.rb +34 -0
  77. data/lib/roadforest/type-handlers/rdf-handler.rb +36 -0
  78. data/lib/roadforest/{content-handling/type-handlers → type-handlers}/rdfa-writer.rb +2 -2
  79. data/lib/roadforest/{content-handling/type-handlers → type-handlers}/rdfa-writer/document-environment.rb +9 -8
  80. data/lib/roadforest/type-handlers/rdfa-writer/environment-decorator.rb +312 -0
  81. data/lib/roadforest/{content-handling/type-handlers → type-handlers}/rdfa-writer/object-environment.rb +3 -3
  82. data/lib/roadforest/{content-handling/type-handlers → type-handlers}/rdfa-writer/property-environment.rb +5 -11
  83. data/lib/roadforest/type-handlers/rdfa-writer/render-engine.rb +427 -0
  84. data/lib/roadforest/{content-handling/type-handlers → type-handlers}/rdfa-writer/render-environment.rb +33 -26
  85. data/lib/roadforest/{content-handling/type-handlers → type-handlers}/rdfa-writer/subject-environment.rb +7 -23
  86. data/lib/roadforest/type-handlers/rdfa.rb +73 -0
  87. data/lib/roadforest/type-handlers/rdfpost.rb +301 -0
  88. data/lib/roadforest/utility/class-registry.rb +23 -5
  89. data/spec/.ctrlp-root +0 -0
  90. data/spec/affordance-augmenter.rb +75 -0
  91. data/spec/affordances-flow.rb +438 -0
  92. data/spec/authorization.rb +34 -0
  93. data/spec/client.rb +13 -12
  94. data/spec/credence-annealer.rb +5 -5
  95. data/spec/focus-list.rb +8 -8
  96. data/spec/full-integration.rb +3 -3
  97. data/spec/graph-copier.rb +4 -4
  98. data/spec/graph-store.rb +19 -31
  99. data/spec/keychain.rb +82 -0
  100. data/spec/rdf-normalization.rb +2 -2
  101. data/spec/rdf-parcel.rb +3 -3
  102. data/spec/rdfa-handler.rb +514 -0
  103. data/spec/rdfpost.rb +96 -0
  104. data/spec/source-rigor.rb +57 -0
  105. data/spec/update-focus.rb +11 -10
  106. metadata +91 -66
  107. data/lib/roadforest/blob-model.rb +0 -53
  108. data/lib/roadforest/content-handling/type-handler.rb +0 -76
  109. data/lib/roadforest/content-handling/type-handlers/jsonld.rb +0 -36
  110. data/lib/roadforest/content-handling/type-handlers/rdf-handler.rb +0 -38
  111. data/lib/roadforest/content-handling/type-handlers/rdfa-writer/render-engine.rb +0 -574
  112. data/lib/roadforest/content-handling/type-handlers/rdfa.rb +0 -175
  113. data/lib/roadforest/content-handling/type-handlers/rdfpost.rb +0 -297
  114. data/lib/roadforest/model.rb +0 -209
  115. data/lib/roadforest/models.rb +0 -2
  116. data/lib/roadforest/rdf/source-rigor.rb +0 -44
  117. data/lib/roadforest/rdf/vocabulary.rb +0 -11
  118. data/lib/roadforest/resource/http/form-parsing.rb +0 -81
  119. data/lib/roadforest/resource/rdf.rb +0 -4
  120. data/spec/form-parsing.rb +0 -1
@@ -1,53 +0,0 @@
1
- require 'roadforest/model'
2
- require 'roadforest/content-handling/type-handlers/jsonld'
3
-
4
- module RoadForest
5
- class BlobModel < Model
6
- TypeHandlers = RoadForest::MediaType::Handlers
7
- class << self
8
- def type_handling
9
- @engine ||= ContentHandling::Engine.new
10
- end
11
-
12
- def add_type(handler, type)
13
- type_handling.add_type(handler, type)
14
- end
15
- alias add add_type
16
- end
17
-
18
- def type_handling
19
- self.class.type_handling
20
- end
21
-
22
- def destination_dir
23
- Pathname.new(services.destination_dir)
24
- end
25
-
26
- def sub_path
27
- params.remainder
28
- end
29
-
30
- def path
31
- destination_dir.join(sub_path)
32
- end
33
-
34
- def retrieve
35
- File::open(path)
36
- end
37
-
38
- def incomplete_path
39
- [path,"incomplete"].join(".")
40
- end
41
-
42
- def update(incoming)
43
- File::open(incomplete_path, "w") do |file|
44
- incoming.each do |chunk|
45
- file.write(chunk)
46
- end
47
- end
48
- Pathname.new(incomplete_path).rename(path)
49
-
50
- return nil
51
- end
52
- end
53
- end
@@ -1,76 +0,0 @@
1
- module RoadForest
2
- module MediaType
3
- module Handlers
4
- class Handler
5
- def network_to_local(base_uri, network)
6
- return network
7
- end
8
-
9
- def local_to_network(base_uri, local)
10
- return local
11
- end
12
-
13
- def parse_for(resource)
14
- source = resource.request_body
15
- model = resource.model
16
- input_data = network_to_local(model.my_url, source)
17
-
18
- update_model(model, input_data)
19
-
20
- renderer = model.type_handling.choose_renderer(resource.request_accept_header)
21
- body = renderer.local_to_network(model.my_url, model.response_data)
22
-
23
- build_response(resource)
24
- end
25
-
26
- def render_for(resource)
27
- model = resource.model
28
- output_data = get_output(model)
29
- local_to_network(model.my_url, output_data)
30
- end
31
-
32
- def add_child_to(resource)
33
- model = resource.model
34
- source = resource.request_body
35
- input_data = network_to_local(model.my_url, source)
36
-
37
- child_for_model(resource.model, input_data)
38
-
39
- build_response(resource)
40
- end
41
-
42
- def build_response(resource)
43
- model = resource.model
44
-
45
- renderer = model.type_handling.choose_renderer(resource.request_accept_header)
46
- body = renderer.local_to_network(model.my_url, model.response_data)
47
-
48
- resource.response_content_type = renderer.content_type_header
49
- resource.response_body = body
50
- if model.response_location
51
- resource.redirect_to(model.response_location)
52
- end
53
- end
54
-
55
- def child_for_model(model, data)
56
- model.add_child(data)
57
- model.processed
58
- end
59
-
60
- def update_model(model, input_data)
61
- result = model.update(input_data)
62
- model.response_data = result
63
- model.processed
64
- result
65
- end
66
-
67
- def get_output(model)
68
- result = model.retrieve
69
- model.response_data = result
70
- model.processed
71
- result
72
- end
73
- end
74
- end
75
- end
76
- end
@@ -1,36 +0,0 @@
1
- require 'json/ld'
2
- require 'roadforest/content-handling/type-handlers/rdf-handler'
3
- module RoadForest
4
- module MediaType
5
- module Handlers
6
- #application/ld+json
7
- class JSONLD < RDFHandler
8
- include RDF::Normalization
9
-
10
- def local_to_network(base_uri, rdf)
11
- raise "Invalid base uri: #{base_uri}" if base_uri.nil?
12
- prefixes = relevant_prefixes_for_graph(rdf)
13
- prefixes.keys.each do |prefix|
14
- prefixes[prefix.to_sym] = prefixes[prefix]
15
- end
16
- JSON::LD::Writer.buffer(:base_uri => base_uri.to_s,
17
- :prefixes => prefixes) do |writer|
18
- rdf.each_statement do |statement|
19
- writer << statement
20
- end
21
- end
22
- end
23
-
24
- def network_to_local(base_uri, source)
25
- raise "Invalid base uri: #{base_uri.inspect}" if base_uri.nil?
26
- graph = ::RDF::Graph.new
27
- reader = JSON::LD::Reader.new(source.to_s, :base_uri => base_uri.to_s)
28
- reader.each_statement do |statement|
29
- graph.insert(statement)
30
- end
31
- graph
32
- end
33
- end
34
- end
35
- end
36
- end
@@ -1,38 +0,0 @@
1
- require 'roadforest/content-handling/type-handler'
2
- require 'roadforest/rdf/normalization'
3
- module RoadForest
4
- module MediaType
5
- module Handlers
6
- class RDFHandler < Handler
7
- include RDF::Normalization
8
-
9
- def get_output(model)
10
- graph = super
11
- root_uri = model.canonical_uri
12
-
13
- graph.each_statement do |statement|
14
- original = statement.dup
15
- if ::RDF::URI === statement.subject and statement.subject.relative?
16
- statement.subject = normalize_resource(root_uri.join(statement.subject))
17
- end
18
-
19
- if ::RDF::URI === statement.object and statement.object.relative?
20
- statement.object = normalize_resource(root_uri.join(statement.object))
21
- end
22
-
23
- if statement != original
24
- graph.delete(original)
25
- graph.insert(statement)
26
- end
27
- end
28
- graph
29
- end
30
-
31
- def child_for_model(model, data)
32
- model.add_graph_child(data)
33
- model.processed
34
- end
35
- end
36
- end
37
- end
38
- end
@@ -1,574 +0,0 @@
1
- require 'roadforest/content-handling/type-handlers/rdfa-writer'
2
- require 'roadforest/content-handling/type-handlers/rdfa-writer/document-environment'
3
- require 'roadforest/content-handling/type-handlers/rdfa-writer/subject-environment'
4
- require 'roadforest/content-handling/type-handlers/rdfa-writer/property-environment'
5
- require 'roadforest/content-handling/type-handlers/rdfa-writer/object-environment'
6
- require 'haml'
7
-
8
- module RoadForest::MediaType
9
- class RDFaWriter
10
- class RenderEngine
11
- # Defines rdf:type of subjects to be emitted at the beginning of the
12
- # document.
13
- # @return [Array<URI>]
14
- attr_accessor :top_classes
15
-
16
- # Defines order of predicates to to emit at begninning of a resource description. Defaults to `[rdf:type, rdfs:label, dc:title]`
17
- # @return [Array<URI>]
18
- attr_accessor :predicate_order
19
-
20
- # Defines order of predicates to use in heading.
21
- # @return [Array<URI>]
22
- attr_accessor :heading_predicates
23
-
24
- attr_accessor :prefixes, :base_uri, :lang, :standard_prefixes, :graph, :titles, :doc_title
25
- attr_accessor :valise, :resource_name, :style_name, :template_cache, :haml_options
26
- attr_reader :debug
27
-
28
- def initialize(graph, debug=nil)
29
- @debug = debug
30
- @graph = graph
31
-
32
- reset
33
-
34
- yield self
35
-
36
- setup
37
- end
38
-
39
- # Reset parser to run again
40
- def reset
41
- @debug_indent = 0
42
- @uri_to_term_or_curie = {}
43
- @uri_to_prefix = {}
44
- @references = Hash.new{|h,k| h[k] = 0}
45
- @prefixes = {}
46
- @serialized = {}
47
- @subjects = {}
48
- @ordered_subjects = []
49
- @titles = {}
50
- @doc_title = ""
51
- end
52
-
53
- def template_cache
54
- @template_cache ||= ::Tilt::Cache.new
55
- end
56
-
57
- def style_name
58
- @style_name ||= "base"
59
- end
60
-
61
- def setup_env(env)
62
- env.heading_predicates = heading_predicates
63
- env.lang = lang
64
- end
65
-
66
- # Increase depth around a method invocation
67
- # @yield
68
- # Yields with no arguments
69
- # @yieldreturn [Object] returns the result of yielding
70
- # @return [Object]
71
- def depth
72
- @debug_indent += 1
73
- ret = yield
74
- @debug_indent -= 1
75
- ret
76
- end
77
-
78
- def templates
79
- @templates ||= [resource_name, style_name, nil].uniq.map do |name|
80
- valise.sub_set(["templates", name].compact.join("/"))
81
- end.inject do |left, right|
82
- left + right
83
- end.handle_templates do |config|
84
- config.add_type("haml", { :template_cache => template_cache, :template_options => haml_options })
85
- end
86
- end
87
-
88
- ##
89
- # Find a template appropriate for the subject.
90
- # Override this method to provide templates based on attributes of a given subject
91
- #
92
- # @param [RDF::URI] subject
93
- # @return [Hash] # return matched matched template
94
- def find_template(kinds)
95
- kind = kinds.shift
96
- templates.contents(kind)
97
- rescue Valise::Errors::NotFound
98
- if kinds.empty?
99
- raise RDF::WriterError, "Missing template for #{context.class.name}" if template.nil?
100
- else
101
- retry
102
- end
103
- end
104
-
105
- def find_environment_template(env)
106
- find_template(env.template_kinds)
107
- end
108
-
109
- # Increase the reference count of this resource
110
- # @param [RDF::Resource] resource
111
- # @return [Integer] resulting reference count
112
- def bump_reference(resource)
113
- @references[resource] += 1
114
- end
115
-
116
- # Return the number of times this node has been referenced in the object position
117
- # @param [RDF::Node] node
118
- # @return [Boolean]
119
- def ref_count(node)
120
- @references[node]
121
- end
122
-
123
- # Add debug event to debug array, if specified
124
- #
125
- # @param [String] message
126
- # @yieldreturn [String] appended to message, to allow for lazy-evaulation of message
127
- def add_debug(message = nil)
128
- return unless ::RoadForest.debug_io || @debug
129
- message ||= ""
130
- message = message + yield if block_given?
131
- msg = "#{' ' * @debug_indent}#{message}"
132
- RoadForest::debug(msg)
133
- @debug << msg.force_encoding("utf-8") if @debug.is_a?(Array)
134
- end
135
-
136
- def setup
137
- add_debug {"\nserialize setup: graph size: #{@graph.size}"}
138
-
139
- preprocess
140
-
141
- @ordered_subjects = order_subjects
142
-
143
- # Take title from first subject having a heading predicate
144
- @doc_title = nil
145
- heading_predicates.each do |pred|
146
- @graph.query(:predicate => pred) do |statement|
147
- titles[statement.subject] ||= statement.object
148
- end
149
- end
150
- title_subject = @ordered_subjects.detect {|subject| titles[subject]}
151
- @doc_title = titles[title_subject]
152
- end
153
-
154
- # Perform any preprocessing of statements required
155
- # @return [ignored]
156
- def preprocess
157
- # Load initial contexts
158
- # Add terms and prefixes to local store for converting URIs
159
- # Keep track of vocabulary from left-most context
160
- [RDF::RDFa::XML_RDFA_CONTEXT, RDF::RDFa::HTML_RDFA_CONTEXT].each do |uri|
161
- ctx = RDF::RDFa::Context.find(uri)
162
- ctx.prefixes.each_pair do |k, v|
163
- @uri_to_prefix[v] = k unless k.to_s == "dcterms"
164
- end
165
-
166
- ctx.terms.each_pair do |k, v|
167
- @uri_to_term_or_curie[v] = k
168
- end
169
-
170
- @vocabulary = ctx.vocabulary.to_s if ctx.vocabulary
171
- end
172
-
173
- # Load defined prefixes
174
- (@prefixes || {}).each_pair do |k, v|
175
- @uri_to_prefix[v.to_s] = k
176
- end
177
- @prefixes = {} # Will define actual used when matched
178
-
179
- # Process each statement to establish CURIEs and Terms
180
- @graph.each {|statement| preprocess_statement(statement)}
181
- add_debug{ "preprocess prefixes: #{@prefixes.inspect}" }
182
- end
183
-
184
- # Order subjects for output. Override this to output subjects in another order.
185
- #
186
- # Uses #top_classes and #base_uri.
187
- # @return [Array<Resource>] Ordered list of subjects
188
- def order_subjects
189
- seen = {}
190
- subjects = []
191
-
192
- # Start with base_uri
193
- if base_uri && @subjects.keys.include?(base_uri)
194
- subjects << base_uri
195
- seen[base_uri] = true
196
- end
197
-
198
- # Add distinguished classes
199
- top_classes.select do |s|
200
- !seen.include?(s)
201
- end.each do |class_uri|
202
- graph.query(:predicate => RDF.type, :object => class_uri).map {|st| st.subject}.sort.uniq.each do |subject|
203
- #add_debug {"order_subjects: #{subject.inspect}"}
204
- subjects << subject
205
- seen[subject] = true
206
- end
207
- end
208
-
209
- # Sort subjects by resources over nodes, ref_counts and the subject URI itself
210
- recursable = @subjects.keys.select do |s|
211
- !seen.include?(s)
212
- end.map do |r|
213
- [r.is_a?(RDF::Node) ? 1 : 0, ref_count(r), r]
214
- end.sort
215
-
216
- add_debug {"order_subjects: #{recursable.inspect}"}
217
-
218
- subjects += recursable.map{|r| r.last}
219
- end
220
-
221
- # Take a hash from predicate uris to lists of values.
222
- # Sort the lists of values. Return a sorted list of properties.
223
- #
224
- # @param [Hash{String => Array<Resource>}] properties A hash of Property to Resource mappings
225
- # @return [Array<String>}] Ordered list of properties. Uses predicate_order.
226
- def order_properties(properties)
227
- # Make sorted list of properties
228
- prop_list = []
229
-
230
- predicate_order.each do |prop|
231
- next unless properties[prop.to_s]
232
- prop_list << prop.to_s
233
- end
234
-
235
- properties.keys.sort.each do |prop|
236
- next if prop_list.include?(prop.to_s)
237
- prop_list << prop.to_s
238
- end
239
-
240
- add_debug {"order_properties: #{prop_list.join(', ')}"}
241
- prop_list
242
- end
243
-
244
- # Perform any statement preprocessing required. This is used to perform reference counts and determine required prefixes.
245
- # @param [RDF::Statement] statement
246
- # @return [ignored]
247
- def preprocess_statement(statement)
248
- #add_debug {"preprocess: #{statement.inspect}"}
249
- bump_reference(statement.subject)
250
- bump_reference(statement.object)
251
- @subjects[statement.subject] = true
252
- get_curie(statement.subject)
253
- get_curie(statement.predicate)
254
- get_curie(statement.object)
255
- get_curie(statement.object.datatype) if statement.object.literal? && statement.object.has_datatype?
256
- end
257
-
258
- def get_curie(resource)
259
- raise RDF::WriterError, "Getting CURIE for #{resource.inspect}, which must be an RDF value" unless resource.is_a? RDF::Value
260
- return resource.to_s unless resource.uri?
261
-
262
- uri = resource.to_s
263
-
264
- curie =
265
- case
266
- when @uri_to_term_or_curie.has_key?(uri)
267
- add_debug {"get_curie(#{uri}): uri_to_term_or_curie #{@uri_to_term_or_curie[uri].inspect}"}
268
- return @uri_to_term_or_curie[uri]
269
- when base_uri && uri.index(base_uri.to_s) == 0
270
- add_debug {"get_curie(#{uri}): base_uri (#{uri.sub(base_uri.to_s, "")})"}
271
- uri.sub(base_uri.to_s, "")
272
- when @vocabulary && uri.index(@vocabulary) == 0
273
- add_debug {"get_curie(#{uri}): vocabulary"}
274
- uri.sub(@vocabulary, "")
275
- when u = @uri_to_prefix.keys.detect {|u| uri.index(u.to_s) == 0}
276
- add_debug {"get_curie(#{uri}): uri_to_prefix"}
277
- prefix = @uri_to_prefix[u]
278
- @prefixes[prefix] = u
279
- uri.sub(u.to_s, "#{prefix}:")
280
- when @standard_prefixes && vocab = RDF::Vocabulary.detect {|v| uri.index(v.to_uri.to_s) == 0}
281
- add_debug {"get_curie(#{uri}): standard_prefixes"}
282
- prefix = vocab.__name__.to_s.split('::').last.downcase
283
- @prefixes[prefix] = vocab.to_uri
284
- uri.sub(vocab.to_uri.to_s, "#{prefix}:")
285
- else
286
- add_debug {"get_curie(#{uri}): none"}
287
- uri
288
- end
289
-
290
- add_debug {"get_curie(#{resource}) => #{curie}"}
291
-
292
- @uri_to_term_or_curie[uri] = curie
293
- rescue ArgumentError => e
294
- raise RDF::WriterError, "Invalid URI #{uri.inspect}: #{e.message}"
295
- end
296
-
297
- def render(context)
298
- add_debug "render"
299
- if context.render_checked
300
- return ""
301
- end
302
- template = find_environment_template(context)
303
- depth do
304
- add_debug{ "template: #{template.file}" }
305
- add_debug{ "context: #{context.inspect}"}
306
-
307
- template.render(context) do |item|
308
- context.yielded(item)
309
- end.sub(/\n\Z/,'')
310
- end
311
- end
312
-
313
- # Mark a subject as done.
314
- # @param [RDF::Resource] subject
315
- # @return [Boolean]
316
- def subject_done(subject)
317
- @serialized[subject] = true
318
- end
319
-
320
- # Determine if the subject has been completed
321
- # @param [RDF::Resource] subject
322
- # @return [Boolean]
323
- def is_done?(subject)
324
- @serialized.include?(subject)
325
- end
326
-
327
-
328
- # @param [RDF::Resource] subject
329
- # @return [Hash{String => Object}]
330
- def properties_for_subject(subject)
331
- properties = {}
332
- @graph.query(:subject => subject) do |st|
333
- key = st.predicate.to_s.freeze
334
- properties[key] ||= []
335
- properties[key] << st.object
336
- end
337
- properties
338
- end
339
-
340
- # @param [Array,NilClass] type
341
- # @param [RDF::Resource] subject
342
- # @return [String] string representation of the specific RDF.type uri
343
- def type_of(type, subject)
344
- # Find appropriate template
345
- curie = case
346
- when subject.node?
347
- subject.to_s if ref_count(subject) > 1
348
- else
349
- get_curie(subject)
350
- end
351
-
352
- typeof = Array(type).map {|r| get_curie(r)}.join(" ")
353
- typeof = nil if typeof.empty?
354
-
355
- # Nodes without a curie need a blank @typeof to generate a subject
356
- typeof ||= "" unless curie
357
-
358
- add_debug {"subject: #{curie.inspect}, typeof: #{typeof.inspect}" }
359
-
360
- typeof.freeze
361
- end
362
-
363
- def list_property_envs(predicate, list_objects)
364
- return list_objects.map do |object|
365
- # Render each list as multiple properties and set :inlist to true
366
- list = RDF::List.new(object, @graph)
367
- list.each_statement {|st| subject_done(st.subject)}
368
-
369
- add_debug {"list: #{list.inspect} #{list.to_a}"}
370
- env = simple_property_env(predicate, list.to_a)
371
- env.inlist = "true"
372
- env
373
- end
374
- end
375
-
376
- def object_env(predicate, object)
377
- subj = subject_env(object)
378
- unless subj.nil?
379
- subj.rel = get_curie(predicate)
380
- return subj
381
- end
382
-
383
- env =
384
- if get_curie(object) == 'rdf:nil'
385
- NilObjectEnvironment.new(self)
386
- elsif object.node?
387
- NodeObjectEnvironment.new(self)
388
- elsif object.uri?
389
- UriObjectEnvironment.new(self)
390
- elsif object.datatype == RDF.XMLLiteral
391
- XMLLiteralObjectEnvironment.new(self)
392
- else
393
- ObjectEnvironment.new(self)
394
- end
395
- env.predicate = predicate
396
- env.object = object
397
- env.inlist = nil
398
-
399
- env
400
- end
401
-
402
- def simple_property_env(predicate, objects)
403
- return nil if objects.to_a.empty?
404
-
405
- env = PropertyEnvironment.new(self)
406
- setup_env(env)
407
- env.object_terms = objects
408
- env.predicate = predicate
409
- env.inlist = nil
410
-
411
- env
412
- end
413
-
414
- def subject_env(subject)
415
- return unless @subjects.include?(subject)
416
- properties = properties_for_subject(subject)
417
-
418
- env = SubjectEnvironment.new(self)
419
- env.base = base_uri
420
- env.predicate_terms = order_properties(properties)
421
- env.property_objects = properties
422
- env.subject = subject
423
- env.typeof = type_of(properties.delete(RDF.type.to_s), subject)
424
-
425
- env
426
- end
427
-
428
- def document_env
429
- env = DocumentEnvironment.new(self)
430
- env.subject_terms = @ordered_subjects
431
- env.title = doc_title
432
- env.prefixes = prefixes
433
- env.lang = lang
434
- env.base = base_uri
435
- env
436
- end
437
-
438
- # Render a single- or multi-valued predicate using
439
- # `haml_template[:property_value]` or `haml_template[:property_values]`.
440
- # Yields each object for optional rendering. The block should only render
441
- # for recursive subject definitions (i.e., where the object is also a
442
- # subject and is rendered underneath the first referencing subject).
443
- #
444
- # If a multi-valued property definition is not found within the template, the writer will use the single-valued property definition multiple times.
445
- #
446
- # @param [Array<RDF::Resource>] predicate
447
- # Predicate to render.
448
- # @param [Array<RDF::Resource>] objects
449
- # List of objects to render. If the list contains only a single element, the :property_value template will be used. Otherwise, the :property_values template is used.
450
- # @param [Hash{Symbol => Object}] options Rendering options passed to Haml render.
451
- # @option options [String] :haml (haml_template[:property_value], haml_template[:property_values])
452
- # Haml template to render. Otherwise, uses `haml_template[:property_value] or haml_template[:property_values]`
453
- # depending on the cardinality of objects.
454
- # @yield object, inlist
455
- # Yields object and if it is contained in a list.
456
- # @yieldparam [RDF::Resource] object
457
- # @yieldparam [Boolean] inlist
458
- # @yieldreturn [String, nil]
459
- # The block should only return a string for recursive object definitions.
460
- # @return String
461
- # The rendered document is returned as a string
462
- #
463
- #
464
- def render_predicate(subject, pred)
465
- pred = RDF::URI(pred) if pred.is_a?(String)
466
- objects = properties_for_subject(subject)[pred.to_s]
467
-
468
- add_debug {"predicate: #{pred.inspect}, objects: #{objects}"}
469
-
470
- return if objects.to_a.empty?
471
-
472
- nonlists, lists = objects.partition do |object|
473
- object == RDF.nil || (l = RDF::List.new(object, @graph)).invalid?
474
- end
475
-
476
- add_debug {"properties with lists: #{lists} non-lists: #{nonlists}"}
477
-
478
- return ([simple_property_env(pred, nonlists)] + list_property_envs(pred, lists)).compact.map do |env|
479
- render(env)
480
- end.join(" ")
481
- end
482
-
483
- def is_list?(object)
484
- !(object == RDF.nil || (l = RDF::List.new(object, @graph)).invalid?)
485
- end
486
-
487
- # @param [RDF::Resource] subject
488
- # @param [Array] prop_list
489
- # @param [Hash] render_opts
490
- # @return [String]
491
- def render_subject(subject)
492
- # See if there's a template based on the sorted concatenation of all types of this subject
493
- # or any type of this subject
494
-
495
- env = subject_env(subject)
496
-
497
- return if env.nil?
498
-
499
- yield env if block_given?
500
-
501
- add_debug {"props: #{env.predicates.inspect}"}
502
-
503
- render(env)
504
- end
505
-
506
- # Render document using `haml_template[:doc]`. Yields each subject to be
507
- # rendered separately.
508
- #
509
- # @param [Array<RDF::Resource>] subjects
510
- # Ordered list of subjects. Template must yield to each subject, which returns
511
- # the serialization of that subject (@see #subject_template)
512
- # @param [Hash{Symbol => Object}] options Rendering options passed to Haml render.
513
- # @option options [RDF::URI] base (nil)
514
- # Base URI added to document, used for shortening URIs within the document.
515
- # @option options [Symbol, String] language (nil)
516
- # Value of @lang attribute in document, also allows included literals to omit
517
- # an @lang attribute if it is equivalent to that of the document.
518
- # @option options [String] title (nil)
519
- # Value of html>head>title element.
520
- # @option options [String] prefix (nil)
521
- # Value of @prefix attribute.
522
- # @option options [String] haml (haml_template[:doc])
523
- # Haml template to render.
524
- # @yield [subject]
525
- # Yields each subject
526
- # @yieldparam [RDF::URI] subject
527
- # @yieldreturn [:ignored]
528
- # @return String
529
- # The rendered document is returned as a string
530
- def render_document
531
- add_debug{ "engine prefixes: #{prefixes.inspect}"}
532
- env = document_env
533
-
534
- yield env if block_given?
535
-
536
- render(env)
537
- end
538
-
539
- # Render a subject using `haml_template[:subject]`.
540
- #
541
- # The _subject_ template may be called either as a top-level element, or recursively under another element if the _rel_ local is not nil.
542
- #
543
- # Yields each predicate/property to be rendered separately (@see #render_property_value and `#render_property_values`).
544
- #
545
- # @param [Array<RDF::Resource>] subject
546
- # Subject to render
547
- # @param [Array<RDF::Resource>] predicates
548
- # Predicates of subject. Each property is yielded for separate rendering.
549
- # @param [Hash{Symbol => Object}] options Rendering options passed to Haml render.
550
- # @option options [String] about (nil)
551
- # About description, a CURIE, URI or Node definition.
552
- # May be nil if no @about is rendered (e.g. unreferenced Nodes)
553
- # @option options [String] resource (nil)
554
- # Resource description, a CURIE, URI or Node definition.
555
- # May be nil if no @resource is rendered
556
- # @option options [String] rel (nil)
557
- # Optional @rel property description, a CURIE, URI or Node definition.
558
- # @option options [String] typeof (nil)
559
- # RDF type as a CURIE, URI or Node definition.
560
- # If :about is nil, this defaults to the empty string ("").
561
- # @option options [:li, nil] element (nil)
562
- # Render with &lt;li&gt;, otherwise with template default.
563
- # @option options [String] haml (haml_template[:subject])
564
- # Haml template to render.
565
- # @yield [predicate]
566
- # Yields each predicate
567
- # @yieldparam [RDF::URI] predicate
568
- # @yieldreturn [:ignored]
569
- # @return String
570
- # The rendered document is returned as a string
571
- # Return Haml template for document from `haml_template[:subject]`
572
- end
573
- end
574
- end