Class: Annotations2triannon::Resource

Inherits:
Object
  • Object
show all
Defined in:
lib/annotations2triannon/resource.rb

Direct Known Subclasses

AnnotationList, IIIFCollection, Manifest

Constant Summary collapse

@@config =
nil

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(uri = nil) ⇒ Resource

Returns a new instance of Resource.



27
28
29
30
31
32
33
34
35
# File 'lib/annotations2triannon/resource.rb', line 27

def initialize(uri=nil)
  @@agent ||= Annotations2triannon::AGENT
  @@config ||= Annotations2triannon.configuration
  if uri =~ /\A#{URI::regexp}\z/
    uri = Addressable::URI.parse(uri.to_s) rescue nil
  end
  raise 'invalid uri' unless uri.instance_of? Addressable::URI
  @iri = uri
end

Instance Attribute Details

#iriObject

Returns the value of attribute iri.



25
26
27
# File 'lib/annotations2triannon/resource.rb', line 25

def iri
  @iri
end

Class Method Details

.http_head_request(url) ⇒ Object



8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
# File 'lib/annotations2triannon/resource.rb', line 8

def self.http_head_request(url)
  uri = nil
  begin
    response = RestClient.head(url)
    uri = response.args[:url]
  rescue
    @@config.logger.error "RestClient.head failed for #{url}"
    begin
      response = RestClient.get(url)
      uri = response.args[:url]
    rescue
      @@config.logger.error "RestClient.get failed for #{url}"
    end
  end
  uri
end

Instance Method Details

#as_jsonldObject

A json-ld object for the rdf resource



246
247
248
# File 'lib/annotations2triannon/resource.rb', line 246

def as_jsonld
  JSON::LD::API::fromRdf(rdf)
end

#idObject



37
38
39
# File 'lib/annotations2triannon/resource.rb', line 37

def id
  @iri.basename
end

#iri_type?(type) ⇒ Boolean

Returns:

  • (Boolean)


41
42
43
# File 'lib/annotations2triannon/resource.rb', line 41

def iri_type?(type)
  iri_types.include? RDF::URI.parse(type)
end

#iri_typesObject



45
46
47
48
# File 'lib/annotations2triannon/resource.rb', line 45

def iri_types
  q = [rdf_uri, RDF.type, :o]
  rdf.query(q).collect {|s| s.object }
end

#provenanceObject

Assert PROV.SoftwareAgent and PROV.generatedAtTime



51
52
53
54
55
56
# File 'lib/annotations2triannon/resource.rb', line 51

def provenance
  s = [rdf_uri, RDF::PROV.SoftwareAgent, @@agent]
  rdf.insert(s)
  s = [rdf_uri, RDF::PROV.generatedAtTime, rdf_now]
  rdf.insert(s)
end

#query_predicate_objects(predicate) ⇒ Array

RDF query to find all objects of a predicate

Parameters:

  • predicate (RDF::URI)

    An RDF predicate, the ?p in ?s ?p ?o

Returns:

  • (Array)

    The objects of predicate, the ?o in ?s ?p ?o



83
84
85
86
# File 'lib/annotations2triannon/resource.rb', line 83

def query_predicate_objects(predicate)
  q = [:s, predicate, :o]
  rdf.query(q).collect {|s| s.object }
end

#query_predicate_subjects(predicate) ⇒ Array

RDF query to find all subjects with a predicate

Parameters:

  • predicate (RDF::URI)

    An RDF predicate, the ?p in ?s ?p ?o

Returns:

  • (Array)

    The subjects with predicate, the ?s in ?s ?p ?o



91
92
93
94
# File 'lib/annotations2triannon/resource.rb', line 91

def query_predicate_subjects(predicate)
  q = [:s, predicate, :o]
  rdf.query(q).collect {|s| s.subject }
end

#rdfObject

This method is often overloaded in subclasses because RDF services use variations in the URL ‘extension’ patterns; e.g. see Loc#rdf and Viaf#rdf



61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
# File 'lib/annotations2triannon/resource.rb', line 61

def rdf
  # TODO: try to retrieve the rdf from a local triple store
  # TODO: if local triple store fails, try remote source(s)
  # TODO: if retrieved from a remote source, save the rdf to a local triple store
  return @rdf unless @rdf.nil?
  uri4rdf = @iri.to_s
  tries = 0
  begin
    tries += 1
    @rdf = RDF::Graph.load(uri4rdf)
  rescue
    sleep 1*tries
    retry if tries < 3
    binding.pry if @@config.debug
    @@config.logger.error("Failed to retrieve RDF for #{uri4rdf}")
    @rdf = nil
  end
end

#rdf_expand_blank_nodes(object) ⇒ RDF::Graph

Returns graph of recursive resolution for a blank node.

Parameters:

  • object (RDF::Node)

    An RDF blank node

Returns:

  • (RDF::Graph)

    graph of recursive resolution for a blank node



122
123
124
125
126
127
128
129
130
131
# File 'lib/annotations2triannon/resource.rb', line 122

def rdf_expand_blank_nodes(object)
  g = RDF::Graph.new
  if object.node?
    rdf.query([object, nil, nil]) do |s,p,o|
      g << [s,p,o]
      g << rdf_expand_blank_nodes(o) if o.node?
    end
  end
  g
end

#rdf_find_object(id) ⇒ RDF::URI

Regexp search to find an object matching a string, if it belongs to @iri

Parameters:

  • id (String)

    A string literal used to construct a Regexp

Returns:

  • (RDF::URI)

    The first object matching the Regexp



99
100
101
102
103
104
105
106
107
# File 'lib/annotations2triannon/resource.rb', line 99

def rdf_find_object(id)
  return nil unless rdf_valid?
  rdf.each_statement do |s|
    if s.subject == @iri.to_s
      return s.object if s.object.to_s =~ Regexp.new(id, Regexp::IGNORECASE)
    end
  end
  nil
end

#rdf_find_subject(id) ⇒ RDF::URI

Regexp search to find a subject matching a string

Parameters:

  • id (String)

    A string literal used to construct a Regexp

Returns:

  • (RDF::URI)

    The first subject matching the Regexp



112
113
114
115
116
117
118
# File 'lib/annotations2triannon/resource.rb', line 112

def rdf_find_subject(id)
  return nil unless rdf_valid?
  rdf.each_subject do |s|
    return s if s.to_s =~ Regexp.new(id, Regexp::IGNORECASE)
  end
  nil
end

#rdf_insert(uriS, uriP, uriO) ⇒ Object


RDF::Graph convenience wrappers



136
137
138
# File 'lib/annotations2triannon/resource.rb', line 136

def rdf_insert(uriS, uriP, uriO)
  @rdf.insert RDF::Statement(uriS, uriP, uriO)
end

#rdf_insert_contributor(uriS, uriO) ⇒ Object



148
149
150
# File 'lib/annotations2triannon/resource.rb', line 148

def rdf_insert_contributor(uriS, uriO)
  rdf_insert(uriS, RDF::SCHEMA.contributor, uriO)
end

#rdf_insert_creator(uriS, uriO) ⇒ Object



145
146
147
# File 'lib/annotations2triannon/resource.rb', line 145

def rdf_insert_creator(uriS, uriO)
  rdf_insert(uriS, RDF::SCHEMA.creator, uriO)
end

#rdf_insert_editor(uriS, uriO) ⇒ Object



151
152
153
# File 'lib/annotations2triannon/resource.rb', line 151

def rdf_insert_editor(uriS, uriO)
  rdf_insert(uriS, RDF::SCHEMA.editor, uriO)
end

#rdf_insert_exampleOfWork(uriS, uriO) ⇒ Object



154
155
156
# File 'lib/annotations2triannon/resource.rb', line 154

def rdf_insert_exampleOfWork(uriS, uriO)
  rdf_insert(uriS, RDF::SCHEMA.exampleOfWork, uriO)
end

#rdf_insert_foafFocus(uriS, uriO) ⇒ Object



157
158
159
160
161
# File 'lib/annotations2triannon/resource.rb', line 157

def rdf_insert_foafFocus(uriS, uriO)
  # http://xmlns.com/foaf/spec/#term_focus
  # relates SKOS:Concept to a 'real world thing'
  rdf_insert(uriS, RDF::FOAF.focus, uriO)
end

#rdf_insert_name(uriS, name) ⇒ Object



162
163
164
165
# File 'lib/annotations2triannon/resource.rb', line 162

def rdf_insert_name(uriS, name)
  rdf_insert(uriS, RDF::FOAF.name, name) if @@config.use_foaf
  rdf_insert(uriS, RDF::SCHEMA.name, name) if @@config.use_schema
end

#rdf_insert_sameAs(uriS, uriO) ⇒ Object



139
140
141
# File 'lib/annotations2triannon/resource.rb', line 139

def rdf_insert_sameAs(uriS, uriO)
  rdf_insert(uriS, RDF::OWL.sameAs, uriO)
end

#rdf_insert_seeAlso(uriS, uriO) ⇒ Object



142
143
144
# File 'lib/annotations2triannon/resource.rb', line 142

def rdf_insert_seeAlso(uriS, uriO)
  rdf_insert(uriS, RDF::RDFS.seeAlso, uriO)
end

#rdf_insert_type(uriS, uriO) ⇒ Object

Methods that assert RDF.type



177
178
179
# File 'lib/annotations2triannon/resource.rb', line 177

def rdf_insert_type(uriS, uriO)
  rdf_insert(uriS, RDF.type, uriO)
end

#rdf_nowObject



167
168
169
# File 'lib/annotations2triannon/resource.rb', line 167

def rdf_now
  RDF::Literal.new(Time.now.utc, :datatype => RDF::XSD.dateTime)
end

#rdf_type_agent(uriS) ⇒ Object



181
182
183
184
185
# File 'lib/annotations2triannon/resource.rb', line 181

def rdf_type_agent(uriS)
  # Note: schema.org has no immediate parent for Person or Organization
  rdf_insert_type(uriS, RDF::FOAF.Agent) if @@config.use_foaf
  rdf_insert_type(uriS, RDF::SCHEMA.Thing) if @@config.use_schema
end

#rdf_type_concept(uriS) ⇒ Object



187
188
189
# File 'lib/annotations2triannon/resource.rb', line 187

def rdf_type_concept(uriS)
  rdf_insert_type(uriS, RDF::SKOS.Concept)
end

#rdf_type_organization(uriS) ⇒ Object



191
192
193
194
# File 'lib/annotations2triannon/resource.rb', line 191

def rdf_type_organization(uriS)
  rdf_insert_type(uriS, RDF::FOAF.Organization) if @@config.use_foaf
  rdf_insert_type(uriS, RDF::SCHEMA.Organization) if @@config.use_schema
end

#rdf_type_person(uriS) ⇒ Object



196
197
198
199
# File 'lib/annotations2triannon/resource.rb', line 196

def rdf_type_person(uriS)
  rdf_insert_type(uriS, RDF::FOAF.Person) if @@config.use_foaf
  rdf_insert_type(uriS, RDF::SCHEMA.Person) if @@config.use_schema
end

#rdf_uriObject



171
172
173
# File 'lib/annotations2triannon/resource.rb', line 171

def rdf_uri
  RDF::URI.new(@iri)
end

#rdf_valid?Boolean

Returns:

  • (Boolean)


201
202
203
# File 'lib/annotations2triannon/resource.rb', line 201

def rdf_valid?
  iri_types.length > 0
end

#resolve_url(url) ⇒ String

Returns The URL that resolves, after permanent redirections.

Parameters:

  • url (String|URI)

    A URL that can be resolved via HTTP request

Returns:

  • (String)

    The URL that resolves, after permanent redirections



212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
# File 'lib/annotations2triannon/resource.rb', line 212

def resolve_url(url)
  begin
    # RestClient does all the response code handling and redirection.
    url = Resource.http_head_request(url)
    if url.nil?
      @@config.logger.warn "#{@iri}\t// #{url}"
    else
      @@config.logger.debug "Mapped #{@iri}\t-> #{url}"
    end
  rescue
    binding.pry if @@config.debug
    @@config.logger.error "unknown http error for #{@iri}"
    url = nil
  end
  url
end

#same_as_org_graphObject



229
230
231
232
233
# File 'lib/annotations2triannon/resource.rb', line 229

def same_as_org_graph
  return @same_as_org_graph unless @same_as_org_graph.nil?
  same_as_url = 'http://sameas.org/rdf?uri=' + URI.encode(@iri.to_s)
  @same_as_org_graph = RDF::Graph.load(same_as_url)
end

#same_as_org_queryObject



234
235
236
237
238
# File 'lib/annotations2triannon/resource.rb', line 234

def same_as_org_query
  # q = SPARQL.parse("SELECT * WHERE { <#{@iri}> <http://www.w3.org/2002/07/owl#sameAs> ?o }")
  q = [rdf_uri, RDF::OWL.sameAs, nil]
  same_as_org_graph.query(q).collect {|s| s.object }
end

#to_jsonldObject

A json-ld serialization of the rdf resource



251
252
253
# File 'lib/annotations2triannon/resource.rb', line 251

def to_jsonld
  rdf.dump(:jsonld, standard_prefixes: true)
end

#to_ttlObject

A turtle serialization of the rdf resource



256
257
258
# File 'lib/annotations2triannon/resource.rb', line 256

def to_ttl
  rdf.dump(:ttl, standard_prefixes: true)
end