class OA::Graph
a wrapper class for RDF::Graph that adds methods specific to OpenAnnotation (www.openannotation.org/spec/core/) Annotation objects. This is intended to be used for an RDF::Graph of a single annotation
Constants
- IIIF_CONTEXT_URL
- OA_CONTEXT_URL
- OA_DATED_CONTEXT_URL
- VERSION
Public Class Methods
@return [RDF::Query] query for a subject :s with type of
RDF::Vocab::OA.Annotation
# File lib/oa/graph.rb, line 36 def self.anno_query q = RDF::Query.new q << [:s, RDF.type, RDF::Vocab::OA.Annotation] end
instantiate this class for an RDF::Graph of a single annotation
# File lib/oa/graph.rb, line 44 def initialize(rdf_graph) @graph = rdf_graph end
given an RDF::Resource (an RDF::Node or RDF::URI), look for all the statements with that object as the subject, and recurse through the graph to find all descendant statements pertaining to the subject @param subject the RDF object to be used as the subject in the graph
query. Should be an RDF::Node or RDF::URI
@param [RDF::Graph] graph @return [Array] all the triples with the given subject
# File lib/oa/graph.rb, line 25 def self.subject_statements(subject, graph) result = [] graph.query([subject, nil, nil]).each { |stmt| result << stmt subject_statements(stmt.object, graph).each { |s| result << s } } result.uniq end
Public Instance Methods
@return [String] The datetime from the annotatedAt property, or nil
# File lib/oa/graph.rb, line 107 def annotated_at solution = @graph.query [nil, RDF::Vocab::OA.annotatedAt, nil] solution.first.object.to_s if solution && solution.size == 1 end
For all bodies that are of type ContentAsText, get the characters as a
single String in the returned Array.
@return [Array<String>] body chars as Strings, in an Array (one element
for each contentAsText body)
# File lib/oa/graph.rb, line 98 def body_chars q = RDF::Query.new q << [nil, RDF::Vocab::OA.hasBody, :body] q << [:body, RDF.type, RDF::Vocab::CNT.ContentAsText] q << [:body, RDF::Vocab::CNT.chars, :body_chars] @graph.query(q).each.collect {|stmt| stmt.body_chars.value} end
@return [String] the id of this annotation as a url string, or nil if it
is a Node
# File lib/oa/graph.rb, line 69 def id_as_url solution = @graph.query self.class.anno_query if solution && solution.size == 1 rdf_resource = solution.first.s rdf_resource.to_s if rdf_resource.is_a?(RDF::URI) # TODO: raise exception if not a URI? end end
@return json-ld representation of graph with IIIF context as a url
# File lib/oa/graph.rb, line 58 def jsonld_iiif inline_context = @graph.dump(:jsonld, context: IIIF_CONTEXT_URL) hash_from_json = JSON.parse(inline_context) hash_from_json['@context'] = IIIF_CONTEXT_URL hash_from_json.to_json end
@return json-ld representation of graph with OpenAnnotation context as a
url
# File lib/oa/graph.rb, line 50 def jsonld_oa inline_context = @graph.dump(:jsonld, context: OA_DATED_CONTEXT_URL) hash_from_json = JSON.parse(inline_context) hash_from_json['@context'] = OA_DATED_CONTEXT_URL hash_from_json.to_json end
transform an outer blank node into a null relative URI
# File lib/oa/graph.rb, line 149 def make_null_relative_uri_out_of_blank_node anno_stmts = @graph.query([nil, RDF.type, RDF::Vocab::OA.Annotation]) anno_rdf_obj = anno_stmts.first.subject if anno_rdf_obj.is_a?(RDF::Node) # use null relative URI representation of blank node anno_subject = RDF::URI.new else # it's already a URI anno_subject = anno_rdf_obj end OA::Graph.subject_statements(anno_rdf_obj, @graph).each { |s| if s.subject == anno_rdf_obj && anno_subject != anno_rdf_obj @graph << RDF::Statement(subject: anno_subject, predicate: s.predicate, object: s.object) @graph.delete s else next end } end
send unknown methods to RDF::Graph
# File lib/oa/graph.rb, line 171 def method_missing(sym, *args, &block) @graph.send sym, *args, &block end
@return [Array<String>] Array of urls expressing the OA
motivated_by
values
# File lib/oa/graph.rb, line 80 def motivated_by q = self.class.anno_query.dup q << [:s, RDF::Vocab::OA.motivatedBy, :motivated_by] # if the motivation object gives junk with .to_s, then the anno is illegal anyway and we're not responsible @graph.query(q).each.collect {|stmt| stmt.motivated_by.to_s} end
@param [RDF::URI] predicate either RDF::Vocab::OA.hasTarget or
RDF::Vocab::OA.hasBody
@return [Array<String>] urls for the predicate, as an Array of Strings
# File lib/oa/graph.rb, line 90 def predicate_urls(predicate) @graph.query([nil, predicate, nil]).each_object.collect {|o| o.to_str.strip if o.is_a?(RDF::URI) }.compact end
remove all RDF::Vocab::OA.hasBody statements and any other statements
associated with body objects
# File lib/oa/graph.rb, line 125 def remove_has_body_statements remove_predicate_and_its_object_statements RDF::Vocab::OA.hasBody end
remove all RDF::Vocab::OA.hasTarget statements and any other statements
associated with body objects
# File lib/oa/graph.rb, line 131 def remove_has_target_statements remove_predicate_and_its_object_statements RDF::Vocab::OA.hasTarget end
remove all RDF::Vocab::OA.hasBody and .hasTarget statements
and any other statements associated with body and target objects, leaving all statements to be stored as part of base object in LDP store
# File lib/oa/graph.rb, line 118 def remove_non_base_statements remove_has_target_statements remove_has_body_statements end
remove all such predicate statements and any other statements associated
with predicates' objects
# File lib/oa/graph.rb, line 137 def remove_predicate_and_its_object_statements(predicate) predicate_stmts = @graph.query([nil, predicate, nil]) predicate_stmts.each { |pstmt| pred_obj = pstmt.object OA::Graph.subject_statements(pred_obj, @graph).each { |s| @graph.delete s } if OA::Graph.subject_statements(pred_obj, @graph) @graph.delete pstmt } end