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

anno_query() click to toggle source

@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
new(rdf_graph) click to toggle source

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
subject_statements(subject, graph) click to toggle source

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

annotated_at() click to toggle source

@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
body_chars() click to toggle source

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
id_as_url() click to toggle source

@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
jsonld_iiif() click to toggle source

@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
jsonld_oa() click to toggle source

@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
make_null_relative_uri_out_of_blank_node() click to toggle source

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
method_missing(sym, *args, &block) click to toggle source

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
motivated_by() click to toggle source

@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
predicate_urls(predicate) click to toggle source

@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_has_body_statements() click to toggle source

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_has_target_statements() click to toggle source

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_non_base_statements() click to toggle source

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_predicate_and_its_object_statements(predicate) click to toggle source

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