Class: Krikri::OriginalRecord

Inherits:
Object
  • Object
show all
Includes:
LDP::Invalidatable, LDP::Resource
Defined in:
app/models/krikri/original_record.rb

Overview

Handles records as harvested, prior to mapping

Defined Under Namespace

Classes: LoadError

Constant Summary

Constants included from LDP::Invalidatable

LDP::Invalidatable::INVALIDATED_BY_URI, LDP::Invalidatable::INVALIDATED_TIME_URI

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Methods included from LDP::Invalidatable

#invalidate!, #invalidated?, #invalidated_at_time, #was_invalidated_by

Methods included from LDP::Resource

#delete!, #etag, #exists?, #get, #http_head, #ldp_connection, #modified_date

Constructor Details

#initialize(identifier) ⇒ OriginalRecord

Note:

calling OriginalRecord.new will instantiate an empty object. Use .load and .build to populate the object on instantiation.

Instantiate an OriginalRecord object with a #local_name matching the argument.

Parameters:

  • identifier (#to_s)

    a string to be prepended to the base URI (container) to form a fully qualified name for the rdf source.

Raises:

  • (ArgumentError)


20
21
22
23
24
# File 'app/models/krikri/original_record.rb', line 20

def initialize(identifier)
  raise ArgumentError, "#{identifier} is an invalid local name" if
    identifier.include?('/')
  @local_name = identifier
end

Instance Attribute Details

#contentObject

Returns the value of attribute content.



8
9
10
# File 'app/models/krikri/original_record.rb', line 8

def content
  @content
end

#content_typeObject



133
134
135
# File 'app/models/krikri/original_record.rb', line 133

def content_type
  @content_type || 'text/xml'
end

#local_nameObject

Returns the value of attribute local_name.



8
9
10
# File 'app/models/krikri/original_record.rb', line 8

def local_name
  @local_name
end

#rdf_subjectObject

Returns the value of attribute rdf_subject.



8
9
10
# File 'app/models/krikri/original_record.rb', line 8

def rdf_subject
  @rdf_subject
end

Class Method Details

.base_uriString

Returns the URI namespace/LDP container for resources of this class.

Returns:

  • (String)

    the URI namespace/LDP container for resources of this class



88
89
90
# File 'app/models/krikri/original_record.rb', line 88

def base_uri
  Krikri::Settings['marmotta']['record_container']
end

.build(identifier, content, content_type = nil) ⇒ OriginalRecord

Note:

Marmotta interprets some content types universally as LDP-RDFSources. Take care when passing new content types through to Marmotta; you may get unexpected errors from the server.

Instantiate and populate an OriginalRecord Resource (new or existing) with the specified content and content type.

Parameters:

  • identifier (#to_s)

    a string representing the #local_name for the resource.

  • content (String, #read)

    a string or IO object containing the content to persist to the LDP NRSource.

  • content_type (String) (defaults to: nil)

    a valid MIME type for the data contained in #content.

Returns:

Raises:

  • when no matching record is found in the LDP datastore



73
74
75
76
77
78
79
80
81
82
83
# File 'app/models/krikri/original_record.rb', line 73

def build(identifier, content, content_type = nil)
  raise(ArgumentError,
        '`content` must be a readable IO object or String.'\
        "Got a #{content.class}") unless
    content.is_a?(String) || content.respond_to?(:read)
  record = new(identifier)
  record.reload if record.exists?
  record.content = content
  record.content_type = content_type
  record
end

.build_uri(local_name) ⇒ RDF::URI

Note:

we use ‘RDF::URI.intern` (rather than `.new`) to avoid allocating memory for a new object for the LDP base URI, taking advantage of `RDF::URI.cache`.

Returns a URI built from the ‘.base_uri` and the `local_name` parameter.

Parameters:

  • localname (#to_s)

    the unique portion of the URI to build; this will be combined with ‘.base_uri` to form the returned URI

Returns:

  • (RDF::URI)

    a URI built from the ‘.base_uri` and the `local_name` parameter



101
102
103
# File 'app/models/krikri/original_record.rb', line 101

def build_uri(local_name)
  RDF::URI.intern(base_uri) / local_name
end

.load(identifier) ⇒ OriginalRecord

Instantiate and populate an existing OriginalRecord Resource.

Parameters:

  • identifier (#to_s)

    a string representing the #local_name or fully qualified URI for the resource. Identifier may have a mime type extension, ie. ‘123.xml’.

Returns:

Raises:

  • (LoadError)

    when no matching record is found in the LDP datastore



36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
# File 'app/models/krikri/original_record.rb', line 36

def load(identifier)
  identifier = identifier.to_s.split('/').last if
    identifier.start_with? base_uri

  if identifier.include?('.')
    record = new(identifier.split('.').first)
  else
    record = new(identifier)
  end

  raise LoadError.new(identifier), 'No record found' unless record.exists?

  if identifier.include?('.')
    record.rdf_subject = "#{base_uri}/#{identifier}"
  else
    record.rdf_subject = nr_uri_from_headers(record.http_head)
  end

  record.reload
end

.nr_uri_from_headers(headers) ⇒ Object

TODO:

figure out how to handle situations where more than one NR is described by the same RDFSource (second file PUT to same URI)

Gets the URI for the ldp:NonRDFSource from the Headers returned by the containing ldp:RDFSource.



112
113
114
115
116
117
118
# File 'app/models/krikri/original_record.rb', line 112

def nr_uri_from_headers(headers)
  links = headers['link'].split(',').select! do |link|
    link.include? 'rel="content"'
  end

  links.first[/.*<(.*)>/, 1]
end

Instance Method Details

#==(other) ⇒ Object



121
122
123
124
125
126
127
# File 'app/models/krikri/original_record.rb', line 121

def ==(other)
  return false unless other.is_a? OriginalRecord
  return false unless local_name == other.local_name
  return false unless content == other.content
  return false unless content_type == other.content_type
  true
end

#rdf_sourceRDF::URI

Returns the URI for the managing RDFSource created for the record.

Returns:

  • (RDF::URI)

    the URI for the managing RDFSource created for the record

See Also:



141
142
143
144
# File 'app/models/krikri/original_record.rb', line 141

def rdf_source
  @rdf_source ||=
    OriginalRecordMetadata.new(self.class.build_uri(local_name))
end

#reloadOriginalRecord

Reloads the record from its LDP URI, updates #content to the response body

Returns:

Raises:

  • (Faraday::ClientError)

    if the server responds with an error status. Faraday::ClientError#response contains the full response.



170
171
172
173
174
175
176
# File 'app/models/krikri/original_record.rb', line 170

def reload
  @rdf_subject ||= self.class.nr_uri_from_headers(http_head)
  response = get(nil, true)
  self.content_type = response.env.response_headers['content-type']
  self.content = response.env.body
  self
end

#save(activity_uri = nil, update_etag = false) ⇒ Boolean

Saves over LDP, passing #content and #headers to the request.

Parameters:

  • activity_uri (defaults to: nil)

    the activity responsible for generation

  • update_etag (defaults to: false)

    forces an http_head request to update of the etag

Returns:

  • (Boolean)

    true for success; else false

Raises:

  • (Faraday::ClientError)

    if the server responds with an error status. Faraday::ClientError#response contains the full response.

See Also:



155
156
157
158
159
160
161
162
163
# File 'app/models/krikri/original_record.rb', line 155

def save(activity_uri = nil, update_etag = false)
  response = super(@content, headers)
  @rdf_subject ||= response.env.response_headers['location']
  http_head(true) if update_etag
  return response unless activity_uri
  rdf_source.wasGeneratedBy = activity_uri
  rdf_source.save
  response
end

#to_sObject



129
130
131
# File 'app/models/krikri/original_record.rb', line 129

def to_s
  content
end