roadforest 0.0.3 → 0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (62) hide show
  1. checksums.yaml +7 -0
  2. data/examples/file-management.rb +7 -9
  3. data/lib/roadforest/application/dispatcher.rb +44 -31
  4. data/lib/roadforest/application/parameters.rb +5 -4
  5. data/lib/roadforest/application/path-provider.rb +14 -1
  6. data/lib/roadforest/application/route-adapter.rb +15 -4
  7. data/lib/roadforest/application/services-host.rb +41 -7
  8. data/lib/roadforest/application.rb +4 -8
  9. data/lib/roadforest/authorization.rb +231 -0
  10. data/lib/roadforest/blob-model.rb +2 -11
  11. data/lib/roadforest/content-handling/engine.rb +12 -6
  12. data/lib/roadforest/content-handling/handler-wrap.rb +45 -0
  13. data/lib/roadforest/content-handling/media-type.rb +20 -12
  14. data/lib/roadforest/content-handling/type-handler.rb +76 -0
  15. data/lib/roadforest/content-handling/type-handlers/jsonld.rb +2 -146
  16. data/lib/roadforest/content-handling/type-handlers/rdf-handler.rb +38 -0
  17. data/lib/roadforest/content-handling/type-handlers/rdfa-writer/document-environment.rb +34 -0
  18. data/lib/roadforest/content-handling/type-handlers/rdfa-writer/object-environment.rb +62 -0
  19. data/lib/roadforest/content-handling/type-handlers/rdfa-writer/property-environment.rb +46 -0
  20. data/lib/roadforest/content-handling/type-handlers/rdfa-writer/render-engine.rb +574 -0
  21. data/lib/roadforest/content-handling/type-handlers/rdfa-writer/render-environment.rb +144 -0
  22. data/lib/roadforest/content-handling/type-handlers/rdfa-writer/subject-environment.rb +80 -0
  23. data/lib/roadforest/content-handling/type-handlers/rdfa-writer.rb +163 -0
  24. data/lib/roadforest/content-handling/type-handlers/rdfa.rb +175 -0
  25. data/lib/roadforest/content-handling/type-handlers/rdfpost.rb +297 -0
  26. data/lib/roadforest/debug.rb +10 -0
  27. data/lib/roadforest/http/graph-response.rb +3 -7
  28. data/lib/roadforest/http/graph-transfer.rb +28 -106
  29. data/lib/roadforest/http/keychain.rb +79 -0
  30. data/lib/roadforest/http/message.rb +9 -1
  31. data/lib/roadforest/http/user-agent.rb +115 -0
  32. data/lib/roadforest/http.rb +8 -0
  33. data/lib/roadforest/model.rb +48 -3
  34. data/lib/roadforest/rdf/graph-focus.rb +5 -3
  35. data/lib/roadforest/rdf/graph-store.rb +4 -2
  36. data/lib/roadforest/rdf/normalization.rb +6 -1
  37. data/lib/roadforest/remote-host.rb +22 -7
  38. data/lib/roadforest/resource/rdf/read-only.rb +15 -1
  39. data/lib/roadforest/templates/base/doc.haml +13 -0
  40. data/lib/roadforest/templates/base/property_value.haml +12 -0
  41. data/lib/roadforest/templates/base/property_values.haml +6 -0
  42. data/lib/roadforest/templates/base/subject.haml +4 -0
  43. data/lib/roadforest/templates/distiller/doc.haml +20 -0
  44. data/lib/roadforest/templates/distiller/nil-object.haml +1 -0
  45. data/lib/roadforest/templates/distiller/property_value.haml +7 -0
  46. data/lib/roadforest/templates/distiller/property_values.haml +7 -0
  47. data/lib/roadforest/templates/distiller/subject.haml +5 -0
  48. data/lib/roadforest/templates/min/doc.haml +10 -0
  49. data/lib/roadforest/templates/min/property_values.haml +7 -0
  50. data/lib/roadforest/templates/min/subject.haml +2 -0
  51. data/lib/roadforest/templates/nil-object.haml +0 -0
  52. data/lib/roadforest/templates/node-object.haml +1 -0
  53. data/lib/roadforest/templates/object.haml +1 -0
  54. data/lib/roadforest/templates/uri-object.haml +1 -0
  55. data/lib/roadforest/templates/xml-literal-object.haml +1 -0
  56. data/lib/roadforest/utility/class-registry.rb +4 -0
  57. data/spec/client.rb +119 -77
  58. data/spec/{excon-adapater.rb → excon-adapter.rb} +4 -0
  59. data/spec/full-integration.rb +6 -2
  60. data/spec/graph-store.rb +1 -1
  61. data/spec/media-types.rb +29 -2
  62. metadata +102 -125
@@ -0,0 +1,144 @@
1
+ require 'roadforest/content-handling/type-handlers/rdfa-writer'
2
+ module RoadForest::MediaType
3
+ class RDFaWriter
4
+ class RenderEnvironment
5
+ attr_accessor :heading_predicates, :lang
6
+
7
+ def initialize(engine)
8
+ @_engine = engine
9
+ end
10
+
11
+ def add_debug(msg = nil, &block)
12
+ @_engine.add_debug(msg, &block)
13
+ end
14
+
15
+ def inspect
16
+ "<#{self.class.name}:#{"%x" % self.object_id} #{instance_variables.map do |name|
17
+ next if name == :@_engine
18
+ "#{name}=#{instance_variable_get(name).inspect}"
19
+ end.compact.join(" ")}>"
20
+ end
21
+ # Display a subject.
22
+ #
23
+ # If the Haml template contains an entry matching the subject's rdf:type URI, that entry will be used as the template for this subject and it's properties.
24
+ #
25
+ # @example Displays a subject as a Resource Definition:
26
+ # <div typeof="rdfs:Resource" about="http://example.com/resource">
27
+ # <h1 property="dc:title">label</h1>
28
+ # <ul>
29
+ # <li content="2009-04-30T06:15:51Z" property="dc:created">2009-04-30T06:15:51+00:00</li>
30
+ # </ul>
31
+ # </div>
32
+ #
33
+ # @param [RDF::Resource] subject
34
+ # @param [Hash{Symbol => Object}] options
35
+ # @option options [:li, nil] :element(:div)
36
+ # Serialize using &lt;li&gt; rather than template default element
37
+ # @option options [RDF::Resource] :rel (nil)
38
+ # Optional @rel property
39
+ # @return [String]
40
+ def subject(subject, &block)
41
+ @_engine.render_subject(subject, &block)
42
+ end
43
+
44
+ def is_subject?
45
+ false
46
+ end
47
+
48
+ def literal?
49
+ false
50
+ end
51
+
52
+ def render_checked
53
+ false
54
+ end
55
+
56
+ # Haml rendering helper. Return CURIE for the literal datatype, if the
57
+ # literal is a typed literal.
58
+ #
59
+ # @param [RDF::Resource] literal
60
+ # @return [String, nil]
61
+ # @raise [RDF::WriterError]
62
+ def get_dt_curie(literal)
63
+ raise RDF::WriterError, "Getting datatype CURIE for #{literal.inspect}, which must be a literal" unless literal.is_a?(RDF::Literal)
64
+ get_curie(literal.datatype) if literal.literal? && literal.datatype?
65
+ end
66
+
67
+ # Haml rendering helper. Return language for plain literal, if there is no language, or it is the same as the document, return nil
68
+ #
69
+ # @param [RDF::Literal] literal
70
+ # @return [Symbol, nil]
71
+ # @raise [RDF::WriterError]
72
+ def get_lang(literal)
73
+ raise RDF::WriterError, "Getting datatype CURIE for #{literal.inspect}, which must be a literal" unless literal.is_a?(RDF::Literal)
74
+ literal.language if literal.literal? && literal.language && literal.language.to_s != @_engine.lang.to_s
75
+ end
76
+
77
+ # Haml rendering helper. Data to be added to a @content value
78
+ #
79
+ # @param [RDF::Literal] literal
80
+ # @return [String, nil]
81
+ # @raise [RDF::WriterError]
82
+ def get_content(literal)
83
+ raise RDF::WriterError, "Getting content for #{literal.inspect}, which must be a literal" unless literal.is_a?(RDF::Literal)
84
+ case literal
85
+ when RDF::Literal::Date, RDF::Literal::Time, RDF::Literal::DateTime
86
+ literal.to_s
87
+ end
88
+ end
89
+
90
+ # Haml rendering helper. Display value for object, may be non-canonical if get_content returns a non-nil value
91
+ #
92
+ # @param [RDF::Literal] literal
93
+ # @return [String]
94
+ # @raise [RDF::WriterError]
95
+ def get_value(literal)
96
+ raise RDF::WriterError, "Getting value for #{literal.inspect}, which must be a literal" unless literal.is_a?(RDF::Literal)
97
+ case literal
98
+ when RDF::Literal::Date
99
+ literal.object.strftime("%A, %d %B %Y")
100
+ when RDF::Literal::Time
101
+ literal.object.strftime("%H:%M:%S %Z").sub(/\+00:00/, "UTC")
102
+ when RDF::Literal::DateTime
103
+ literal.object.strftime("%H:%M:%S %Z on %A, %d %B %Y").sub(/\+00:00/, "UTC")
104
+ else
105
+ literal.to_s
106
+ end
107
+ rescue
108
+ literal.to_s # When all else fails ...
109
+ end
110
+
111
+ # Haml rendering helper. Return an appropriate label for a resource.
112
+ #
113
+ # @param [RDF::Resource] resource
114
+ # @return [String]
115
+ # @raise [RDF::WriterError]
116
+ def get_predicate_name(resource)
117
+ raise RDF::WriterError, "Getting predicate name for #{resource.inspect}, which must be a resource" unless resource.is_a?(RDF::Resource)
118
+ get_curie(resource)
119
+ end
120
+
121
+ # rendering helper. Return appropriate, term, CURIE or URI for the given
122
+ # resource.
123
+ #
124
+ # @param [RDF::Value] resource
125
+ # @return [String] value to use to identify URI
126
+ # @raise [RDF::WriterError]
127
+ def get_curie(resource)
128
+ @_engine.get_curie(resource)
129
+ end
130
+
131
+ ##
132
+ # Haml rendering helper. Escape entities to avoid whitespace issues.
133
+ #
134
+ # # In addtion to "&<>, encode \n and \r to ensure that whitespace is properly preserved
135
+ #
136
+ # @param [String] str
137
+ # @return [String]
138
+ # Entity-encoded string
139
+ def escape_entities(str)
140
+ CGI.escapeHTML(str).gsub(/[\n\r]/) {|c| '&#x' + c.unpack('h').first + ';'}
141
+ end
142
+ end
143
+ end
144
+ end
@@ -0,0 +1,80 @@
1
+ require 'roadforest/content-handling/type-handlers/rdfa-writer/render-environment'
2
+ module RoadForest::MediaType
3
+ class RDFaWriter
4
+ class SubjectEnvironment < RenderEnvironment
5
+ attr_accessor :base, :element, :predicate_terms, :property_objects, :rel, :inlist, :subject, :typeof
6
+
7
+ # Write a predicate with one or more values.
8
+ #
9
+ # Values may be a combination of Literal and Resource (Node or URI).
10
+ # @param [RDF::Resource] predicate
11
+ # Predicate to serialize
12
+ # @param [Array<RDF::Resource>] objects
13
+ # Objects to serialize
14
+ # @return [String]
15
+ def predicate(predicate)
16
+ @_engine.render_predicate(subject, predicate)
17
+ end
18
+
19
+ def attrs
20
+ {:rel => rel, :resource => (about || resource), :typeof => typeof, :inlist => inlist}
21
+ end
22
+
23
+ def is_subject?
24
+ true
25
+ end
26
+
27
+ def predicates
28
+ enum_for(:each_predicate)
29
+ end
30
+
31
+ def each_predicate
32
+ predicate_terms.each do |predicate|
33
+ predicate = RDF::URI(predicate) if predicate.is_a?(String)
34
+ objects = property_objects[predicate.to_s]
35
+ next if objects.nil? or objects.empty?
36
+
37
+ nonlists, lists = objects.partition do |object|
38
+ !@_engine.is_list?(object)
39
+ end
40
+
41
+ add_debug {"properties with lists: #{lists} non-lists: #{nonlists}"}
42
+
43
+ ([@_engine.simple_property_env(predicate, nonlists)] + @_engine.list_property_envs(predicate, lists)).compact.each do |env|
44
+ yield(env)
45
+ end
46
+ end
47
+ end
48
+
49
+ def template_kinds
50
+ %w{subject}
51
+ end
52
+
53
+ def render_checked
54
+ return true if @_engine.is_done?(subject)
55
+ @_engine.subject_done(subject)
56
+ return false
57
+ end
58
+
59
+ def about
60
+ if rel.nil?
61
+ get_curie(subject)
62
+ else
63
+ nil
64
+ end
65
+ end
66
+
67
+ def resource
68
+ if rel.nil?
69
+ nil
70
+ else
71
+ get_curie(subject)
72
+ end
73
+ end
74
+
75
+ def yielded(pred)
76
+ @_engine.render(pred)
77
+ end
78
+ end
79
+ end
80
+ end
@@ -0,0 +1,163 @@
1
+ require 'cgi'
2
+ require 'roadforest/debug'
3
+ require 'rdf/rdfa'
4
+
5
+ module RoadForest::MediaType
6
+ ##
7
+ # An RDFa 1.1 serialiser in Ruby. The RDFa serializer makes use of Haml templates, allowing runtime-replacement with alternate templates. Note, however, that templates should be checked against the W3C test suite to ensure that valid RDFa is emitted.
8
+ #
9
+ # Note that the natural interface is to write a whole graph at a time. Writing statements or Triples will create a graph to add them to and then serialize the graph.
10
+ #
11
+ # The writer will add prefix definitions, and use them for creating @prefix definitions, and minting CURIEs
12
+ #
13
+ # @example Obtaining a RDFa writer class
14
+ # RDF::Writer.for(:html) => RDF::RDFa::Writer
15
+ # RDF::Writer.for("etc/test.html")
16
+ # RDF::Writer.for(:file_name => "etc/test.html")
17
+ # RDF::Writer.for(:file_extension => "html")
18
+ # RDF::Writer.for(:content_type => "application/xhtml+xml")
19
+ # RDF::Writer.for(:content_type => "text/html")
20
+ #
21
+ # @example Serializing RDF graph into an XHTML+RDFa file
22
+ # RDF::RDFa::Write.open("etc/test.html") do |writer|
23
+ # writer << graph
24
+ # end
25
+ #
26
+ # @example Serializing RDF statements into an XHTML+RDFa file
27
+ # RDF::RDFa::Writer.open("etc/test.html") do |writer|
28
+ # graph.each_statement do |statement|
29
+ # writer << statement
30
+ # end
31
+ # end
32
+ #
33
+ # @example Serializing RDF statements into an XHTML+RDFa string
34
+ # RDF::RDFa::Writer.buffer do |writer|
35
+ # graph.each_statement do |statement|
36
+ # writer << statement
37
+ # end
38
+ # end
39
+ #
40
+ # @example Creating @base and @prefix definitions in output
41
+ # RDF::RDFa::Writer.buffer(:base_uri => "http://example.com/", :prefixes => {
42
+ # :foaf => "http://xmlns.com/foaf/0.1/"}
43
+ # ) do |writer|
44
+ # graph.each_statement do |statement|
45
+ # writer << statement
46
+ # end
47
+ # end
48
+ #
49
+ # @author [Gregg Kellogg](http://kellogg-assoc.com/)
50
+ class RDFaWriter < RDF::Writer
51
+ HAML_OPTIONS = {
52
+ :ugly => true, # to preserve whitespace without using entities
53
+ }
54
+
55
+ # @return [Graph] Graph of statements serialized
56
+ attr_accessor :graph
57
+
58
+ # @return [RDF::URI] Base URI used for relativizing URIs
59
+ attr_accessor :base_uri
60
+
61
+ ##
62
+ # Initializes the RDFa writer instance.
63
+ #
64
+ # @param [IO, File] output
65
+ # the output stream
66
+ # @param [Hash{Symbol => Object}] options
67
+ # any additional options
68
+ # @option options [Boolean] :canonicalize (false)
69
+ # whether to canonicalize literals when serializing
70
+ # @option options [Hash] :prefixes (Hash.new)
71
+ # the prefix mappings to use
72
+ # @option options [#to_s] :base_uri (nil)
73
+ # the base URI to use when constructing relative URIs, set as html>head>base.href
74
+ # @option options [Boolean] :validate (false)
75
+ # whether to validate terms when serializing
76
+ # @option options [#to_s] :lang (nil)
77
+ # Output as root @lang attribute, and avoid generation _@lang_ where possible
78
+ # @option options [Boolean] :standard_prefixes (false)
79
+ # Add standard prefixes to _prefixes_, if necessary.
80
+ # @option options [Array<RDF::URI>] :top_classes ([RDF::RDFS.Class])
81
+ # Defines rdf:type of subjects to be emitted at the beginning of the document.
82
+ # @option options [Array<RDF::URI>] :predicate_order ([RDF.type, RDF::RDFS.label, RDF::DC.title])
83
+ # Defines order of predicates to to emit at begninning of a resource description..
84
+ # @option options [Array<RDF::URI>] :heading_predicates ([RDF::RDFS.label, RDF::DC.title])
85
+ # Defines order of predicates to use in heading.
86
+ # @option options [String, Symbol, Hash{Symbol => String}] :haml (DEFAULT_HAML) HAML templates used for generating code
87
+ # @option options [Hash] :haml_options (HAML_OPTIONS)
88
+ # Options to pass to Haml::Engine.new. Default options set `:ugly => false` to ensure that whitespace in literals with newlines is properly preserved.
89
+ # @yield [writer]
90
+ # @yieldparam [RDF::Writer] writer
91
+ def initialize(output = $stdout, options = {}, &block)
92
+ super do
93
+ @graph = RDF::Graph.new
94
+ @valise = nil
95
+
96
+ block.call(self) if block_given?
97
+ end
98
+ end
99
+
100
+ ##
101
+ # Write whole graph
102
+ #
103
+ # @param [Graph] graph
104
+ # @return [void]
105
+ def write_graph(graph)
106
+ @graph = graph
107
+ end
108
+
109
+ ##
110
+ # Addes a statement to be serialized
111
+ # @param [RDF::Statement] statement
112
+ # @return [void]
113
+ # @raise [RDF::WriterError] if validating and attempting to write an invalid {RDF::Term}.
114
+ def write_statement(statement)
115
+ raise RDF::WriterError, "Statement #{statement.inspect} is invalid" if validate? && statement.invalid?
116
+ @graph.insert(statement)
117
+ end
118
+
119
+ ##
120
+ # Addes a triple to be serialized
121
+ # @param [RDF::Resource] subject
122
+ # @param [RDF::URI] predicate
123
+ # @param [RDF::Value] object
124
+ # @return [void]
125
+ # @raise [NotImplementedError] unless implemented in subclass
126
+ # @abstract
127
+ # @raise [RDF::WriterError] if validating and attempting to write an invalid {RDF::Term}.
128
+ def write_triple(subject, predicate, object)
129
+ write_statement Statement.new(subject, predicate, object)
130
+ end
131
+
132
+ ##
133
+ # Outputs the XHTML+RDFa representation of all stored triples.
134
+ #
135
+ # @return [void]
136
+ def write_epilogue
137
+ require 'roadforest/content-handling/type-handlers/rdfa-writer/render-engine'
138
+ @base_uri = RDF::URI(@options[:base_uri]) if @options[:base_uri]
139
+ @lang = @options[:lang]
140
+ @debug = @options[:debug]
141
+ engine = RenderEngine.new(@graph, @debug) do |engine|
142
+ engine.valise = Valise.define do
143
+ ro up_to("lib") + "roadforest"
144
+ end
145
+ engine.style_name = @options[:haml]
146
+ engine.base_uri = base_uri
147
+ engine.lang = @lang
148
+ engine.standard_prefixes = @options[:standard_prefixes]
149
+ engine.top_classes = @options[:top_classes] || [RDF::RDFS.Class]
150
+ engine.predicate_order = @options[:predicate_order] || [RDF.type, RDF::RDFS.label, RDF::DC.title]
151
+ engine.heading_predicates = @options[:heading_predicates] || [RDF::RDFS.label, RDF::DC.title]
152
+ engine.haml_options = @options[:haml_options]
153
+ end
154
+
155
+ engine.prefixes.merge! @options[:prefixes] unless @options[:prefixes].nil?
156
+
157
+ # Generate document
158
+ rendered = engine.render_document
159
+
160
+ @output.write(rendered)
161
+ end
162
+ end
163
+ end
@@ -0,0 +1,175 @@
1
+ require 'rdf/rdfa' #XXX Otherwise json-ld grabs RDFa documents. Awaiting fix upstream
2
+ require 'roadforest/content-handling/type-handlers/rdf-handler'
3
+ module RoadForest
4
+ module MediaType
5
+ module Handlers
6
+ class RESTfulRDFaWriter < ::RDF::RDFa::Writer
7
+ HAML = ::RDF::RDFa::Writer::BASE_HAML.merge(:property_values => %q{
8
+ - objects.each do |object|
9
+ /
10
+ = object.inspect
11
+ %div.property
12
+ %span.label
13
+ = get_predicate_name(predicate)
14
+ %ul
15
+ - objects.each do |object|
16
+ - if res = yield(object, :inlist => inlist, :element => :li)
17
+ != res
18
+ - elsif object.node?
19
+ %li{:property => get_curie(predicate), :resource => get_curie(object), :inlist => inlist}= get_curie(object)
20
+ - elsif object.uri?
21
+ %li
22
+ %a{:property => get_curie(predicate), :href => object.to_s, :inlist => inlist}= object.to_s
23
+ - elsif object.datatype == RDF.XMLLiteral
24
+ %li{:property => get_curie(predicate), :lang => get_lang(object), :datatype => get_curie(object.datatype), :inlist => inlist}<!= get_value(object)
25
+ - else
26
+ %li{:property => get_curie(predicate), :content => get_content(object), :lang => get_lang(object), :datatype => get_dt_curie(object), :inlist => inlist}= escape_entities(get_value(object))
27
+ })
28
+
29
+ def initialize(output = $stdout, options = nil, &block)
30
+ options ||= {}
31
+ options = {:haml => HAML}
32
+ super(output, options, &block)
33
+ end
34
+
35
+
36
+ # Write a predicate with one or more values.
37
+ #
38
+ # Values may be a combination of Literal and Resource (Node or URI).
39
+ # @param [RDF::Resource] predicate
40
+ # Predicate to serialize
41
+ # @param [Array<RDF::Resource>] objects
42
+ # Objects to serialize
43
+ # @return [String]
44
+ def predicate(predicate, objects, options = nil)
45
+ add_debug {"predicate: #{predicate.inspect}, objects: #{objects}"}
46
+
47
+ return if objects.to_a.empty?
48
+
49
+ add_debug {"predicate: #{get_curie(predicate)}"}
50
+ render_property(predicate, objects, options || {}) do |o, opts|
51
+ # Yields each object, for potential recursive definition.
52
+ # If nil is returned, a leaf is produced
53
+ opts = {:rel => get_curie(predicate), :element => (:li if objects.length > 1)}.merge(opts||{})
54
+
55
+ if !is_done?(o) && @subjects.include?(o)
56
+ depth {subject(o, opts)}
57
+ end
58
+ end
59
+ end
60
+
61
+
62
+ # Render a single- or multi-valued predicate using
63
+ # `haml_template[:property_value]` or
64
+ # `haml_template[:property_values]`. Yields each object for optional
65
+ # rendering. The block should only render for recursive subject
66
+ # definitions (i.e., where the object is also a subject and is rendered
67
+ # underneath the first referencing subject).
68
+ #
69
+ # If a multi-valued property definition is not found within the template, the writer will use the single-valued property definition multiple times.
70
+ #
71
+ # @param [Array<RDF::Resource>] predicate
72
+ # Predicate to render.
73
+ # @param [Array<RDF::Resource>] objects
74
+ # 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.
75
+ # @param [Hash{Symbol => Object}] options Rendering options passed to Haml render.
76
+ # @option options [String] haml (haml_template[:property_value], haml_template[:property_values])
77
+ # Haml template to render. Otherwise, uses `haml_template[:property_value] or haml_template[:property_values]`
78
+ # depending on the cardinality of objects.
79
+ # @yield [object]
80
+ # Yields object.
81
+ # @yieldparam [RDF::Resource] object
82
+ # @yieldreturn [String, nil]
83
+ # The block should only return a string for recursive object definitions.
84
+ # @return String
85
+ # The rendered document is returned as a string
86
+ def render_property(predicate, objects, options = {}, &block)
87
+ add_debug {"render_property(#{predicate}): #{objects.inspect}"}
88
+ # If there are multiple objects, and no :property_values is defined, call recursively with
89
+ # each object
90
+
91
+ template = options[:haml]
92
+ template ||= objects.length > 1 ? haml_template[:property_values] : haml_template[:property_value]
93
+
94
+ # Separate out the objects which are lists and render separately
95
+ list_objects = objects.select {|o| o != ::RDF.nil && ::RDF::List.new(o, @graph).valid?}
96
+ unless list_objects.empty?
97
+ # Render non-list objects
98
+ add_debug {"properties with lists: non-lists: #{objects - list_objects} lists: #{list_objects}"}
99
+ nl = render_property(predicate, objects - list_objects, options, &block) unless objects == list_objects
100
+ return nl.to_s + list_objects.map do |object|
101
+ # Render each list as multiple properties and set :inlist to true
102
+ list = ::RDF::List.new(object, @graph)
103
+ list.each_statement {|st| subject_done(st.subject)}
104
+
105
+ add_debug {"list: #{list.inspect} #{list.to_a}"}
106
+ render_property(predicate, list.to_a, options.merge(:inlist => "true"), &block)
107
+ end.join(" ")
108
+ end
109
+
110
+ if objects.length > 1 && template.nil?
111
+ # Uf there is no property_values template, render each property using property_value template
112
+ objects.map do |object|
113
+ render_property(predicate, [object], options, &block)
114
+ end.join(" ")
115
+ else
116
+ raise ::RDF::WriterError, "Missing property template" if template.nil?
117
+
118
+ template = options[:haml] || (
119
+ objects.to_a.length > 1 &&
120
+ haml_template.has_key?(:property_values) ?
121
+ :property_values :
122
+ :property_value)
123
+ options = {
124
+ :objects => objects,
125
+ :object => objects.first,
126
+ :predicate => predicate,
127
+ :property => get_curie(predicate),
128
+ :rel => get_curie(predicate),
129
+ :inlist => nil,
130
+ }.merge(options)
131
+ hamlify(template, options) do |object, options|
132
+ yield(object, options) if block_given?
133
+ end
134
+ end
135
+ end
136
+
137
+ end
138
+
139
+ #text/html;q=1;rdfa
140
+ #image/svg+xml;q=1;rdfa
141
+ #application/xhtml+xml;q=1;rdfa
142
+ #text/html
143
+ #image/svg+xml
144
+ #application/xhtml+xml
145
+ class RDFa < RDFHandler
146
+ include RDF::Normalization
147
+
148
+ def local_to_network(base_uri, rdf)
149
+ raise "Invalid base uri: #{base_uri}" if base_uri.nil?
150
+ prefixes = relevant_prefixes_for_graph(rdf)
151
+ prefixes.keys.each do |prefix|
152
+ prefixes[prefix.to_sym] = prefixes[prefix]
153
+ end
154
+ #::RDF::RDFa.debug = true
155
+ RESTfulRDFaWriter.buffer(:base_uri => base_uri.to_s,
156
+ :prefixes => prefixes) do |writer|
157
+ rdf.each_statement do |statement|
158
+ writer << statement
159
+ end
160
+ end
161
+ end
162
+
163
+ def network_to_local(base_uri, source)
164
+ raise "Invalid base uri: #{base_uri.inspect}" if base_uri.nil?
165
+ graph = ::RDF::Graph.new
166
+ reader = ::RDF::RDFa::Reader.new(source.to_s, :base_uri => base_uri.to_s)
167
+ reader.each_statement do |statement|
168
+ graph.insert(statement)
169
+ end
170
+ graph
171
+ end
172
+ end
173
+ end
174
+ end
175
+ end