Class: AtlasRb::Resource
- Inherits:
-
Object
- Object
- AtlasRb::Resource
- Extended by:
- FaradayHelper
- Defined in:
- lib/atlas_rb/resource.rb
Overview
Abstract base for every Atlas resource type.
Subclasses define a ROUTE constant (e.g. "/communities/") and override
whichever of find / create / destroy / update / metadata / mods apply.
The Resource class itself ships four endpoints that are not
type-specific: a generic resolver, an XML preview helper, a permissions
lookup, and an audit-event history fetch.
The Atlas resource hierarchy is:
{Community} → {Collection} → {Work} → {FileSet} → {Blob}
Subclasses extend FaradayHelper so that connection(...) and
multipart(...) are available as class methods.
Direct Known Subclasses
Blob, Collection, Community, Compilation, Delegate, FileSet, Person, Work
Constant Summary
Constants included from FaradayHelper
FaradayHelper::ASSERTION_AUDIENCE, FaradayHelper::ASSERTION_ISSUER, FaradayHelper::ASSERTION_TTL, FaradayHelper::INSTRUMENTATION_EVENT
Class Method Summary collapse
-
.descendant_works(id, page: nil, per_page: nil, include_linked: nil, nuid: nil, on_behalf_of: nil) ⇒ AtlasRb::Mash?
Every Work beneath a resource, at any depth — the structural counterpart to Compilation.contents.
-
.find(id, nuid: nil, on_behalf_of: nil) ⇒ Hash{String => String, Hash}?
Resolve any Atlas resource by ID without knowing its type up front.
-
.find_many(ids, nuid: nil, on_behalf_of: nil) ⇒ Array<AtlasRb::Mash>
Resolve many resources by NOID in a single round-trip.
-
.history(id, nuid: nil, on_behalf_of: nil) ⇒ AtlasRb::Mash
Fetch the audit-event history for a resource.
-
.mods(id, kind = nil, nuid: nil, on_behalf_of: nil) ⇒ String?
Fetch the CURRENT MODS of any Modsable resource by NOID — the polymorphic sibling of Work.mods / Collection.mods / Community.mods.
-
.mods_version(id, version_id, kind: nil, nuid: nil, on_behalf_of: nil) ⇒ String
Fetch the MODS document as of a specific version.
-
.mods_versions(id, nuid: nil, on_behalf_of: nil) ⇒ AtlasRb::Mash
List the retained MODS versions for a resource.
-
.permissions(id, nuid: nil, on_behalf_of: nil) ⇒ Hash
Fetch the access-control entries for a resource.
-
.preview(xml_path, nuid: nil, on_behalf_of: nil) ⇒ String
Validate a MODS XML document against Atlas's schema without persisting it.
Methods included from FaradayHelper
connection, multipart, system_connection, with_file_part
Class Method Details
.descendant_works(id, page: nil, per_page: nil, include_linked: nil, nuid: nil, on_behalf_of: nil) ⇒ AtlasRb::Mash?
Every Work beneath a resource, at any depth — the structural counterpart
to Compilation.contents. Wraps GET /resources/<id>/descendant_works,
which flattens the resource's full descendant subtree to the Works it
contains, gated to what the caller may read and paginated Solr-side. Gives
a Collection the flatten-to-Works capability a Set already has, so a bulk
export (e.g. hyperion) pages one gated, fast call family instead of the
client-side children → find_many → recurse walk.
Returns the same digest shape as find_many / Compilation.contents
({ "id", "noid", "klass", "title", "thumbnail" }) under a "works" key,
plus a "pagination" envelope (total / page / per_page / pages).
Membership is structural (a_member_of) only; pass
include_linked: true to also surface linked members
(a_linked_member_of). Restricted Works never appear for a caller who may
not read them; tombstoned Works are dropped.
125 126 127 128 129 130 131 132 133 134 135 |
# File 'lib/atlas_rb/resource.rb', line 125 def self.descendant_works(id, page: nil, per_page: nil, include_linked: nil, nuid: nil, on_behalf_of: nil) params = {} params[:page] = page if page params[:per_page] = per_page if per_page params[:include_linked] = include_linked unless include_linked.nil? resp = connection(params, nuid, on_behalf_of: on_behalf_of) .get('/resources/' + id + '/descendant_works') return nil if resp.status == 404 AtlasRb::Mash.new(JSON.parse(resp.body)) end |
.find(id, nuid: nil, on_behalf_of: nil) ⇒ Hash{String => String, Hash}?
Resolve any Atlas resource by ID without knowing its type up front.
The Atlas server returns a single-key JSON object whose key names the
resource type ("community", "collection", "work", etc.); this
method splits that into a normalized { "klass" => ..., "resource" => ... }
pair so callers can dispatch on type.
45 46 47 48 49 50 51 |
# File 'lib/atlas_rb/resource.rb', line 45 def self.find(id, nuid: nil, on_behalf_of: nil) result = fetch_resource('/resources/' + id, nuid: nuid, on_behalf_of: on_behalf_of) return nil if result.nil? AtlasRb::Mash.new("klass" => result.first[0].capitalize, "resource" => result.first[1]) end |
.find_many(ids, nuid: nil, on_behalf_of: nil) ⇒ Array<AtlasRb::Mash>
Resolve many resources by NOID in a single round-trip.
Wraps Atlas's POST /resources/find_many, which returns one lightweight
digest per resolvable resource — { "id", "noid", "klass", "title", "thumbnail", "tombstoned" } — rather than full typed payloads. Use it
anywhere a set of ids would otherwise be resolved with a find-per-id
fan-out (breadcrumb chains, linked-member lists, load-destination
pickers): one HTTP call instead of N.
The ids travel in the request body, so the list is not bounded by
URL length. The result is unordered and may be shorter than the
input — unresolvable ids are dropped silently, and tombstoned
resources come back flagged ("tombstoned" => true) rather than
omitted. Index the result by "noid"; do not assume positional
correspondence with ids.
84 85 86 87 88 89 |
# File 'lib/atlas_rb/resource.rb', line 84 def self.find_many(ids, nuid: nil, on_behalf_of: nil) JSON.parse( connection({}, nuid, on_behalf_of: on_behalf_of) .post('/resources/find_many', JSON.dump(ids: Array(ids)))&.body ).map { |node| AtlasRb::Mash.new(node) } end |
.history(id, nuid: nil, on_behalf_of: nil) ⇒ AtlasRb::Mash
Add pagination support once Atlas's history endpoint exposes page / per_page query params. Today the endpoint returns the full history in one shot.
Fetch the audit-event history for a resource.
Wraps Atlas's GET /resources/<id>/history endpoint, which returns the
full envelope (resource_id + reverse-chronological events array).
The whole envelope is preserved so callers can confirm the events
belong to the requested resource; access events as result["events"].
Authorization errors (401 / 403) are intentionally not caught
here — they surface as raw Faraday responses for the calling
application's rescue layer to translate.
212 213 214 215 216 217 |
# File 'lib/atlas_rb/resource.rb', line 212 def self.history(id, nuid: nil, on_behalf_of: nil) AtlasRb::Mash.new(JSON.parse( connection({}, nuid, on_behalf_of: on_behalf_of) .get('/resources/' + id + '/history')&.body )) end |
.mods(id, kind = nil, nuid: nil, on_behalf_of: nil) ⇒ String?
Fetch the CURRENT MODS of any Modsable resource by NOID — the polymorphic
sibling of Work.mods / Collection.mods / Community.mods. Wraps
GET /resources/<id>/mods[.kind] and returns the raw response body
(not parsed), mirroring the typed wrappers. Lets a caller holding only a
NOID (no type) fetch descriptive MODS in one call, instead of resolving
the klass first to pick the typed route — e.g. a bulk Collection/Set MODS
export that has bare member NOIDs from Collection.children.
245 246 247 248 249 |
# File 'lib/atlas_rb/resource.rb', line 245 def self.mods(id, kind = nil, nuid: nil, on_behalf_of: nil) connection({}, nuid, on_behalf_of: on_behalf_of).get( '/resources/' + id + '/mods' + (kind.to_s.empty? ? '' : ".#{kind}") )&.body end |
.mods_version(id, version_id, kind: nil, nuid: nil, on_behalf_of: nil) ⇒ String
Fetch the MODS document as of a specific version.
Wraps Atlas's GET /resources/<id>/mods/versions/<version_id> and
returns the raw response body (not parsed) — mirroring
Work.mods. Pass a version_id obtained from mods_versions (an
opaque OCFL vN label).
Only XML is version-recoverable: the JSON access copy is overwritten in
place, so the server serves historical XML (the default). kind: is
accepted for parity with Work.mods but XML is currently the only
supported format. An unknown version yields a 404 (raw Faraday
response).
320 321 322 323 324 325 |
# File 'lib/atlas_rb/resource.rb', line 320 def self.mods_version(id, version_id, kind: nil, nuid: nil, on_behalf_of: nil) connection({}, nuid, on_behalf_of: on_behalf_of).get( '/resources/' + id + '/mods/versions/' + version_id + (kind.to_s.empty? ? '' : ".#{kind}") )&.body end |
.mods_versions(id, nuid: nil, on_behalf_of: nil) ⇒ AtlasRb::Mash
List the retained MODS versions for a resource.
Wraps Atlas's GET /resources/<id>/mods/versions, which returns the
full envelope — resource_id plus a reverse-chronological versions
array — as an AtlasRb::Mash. Each version descriptor mirrors the
audit-event shape (version_id, created, actor_nuid,
on_behalf_of_nuid, source, note) so the two streams render with
the same helpers; actor fields are correlated from the audit log and
may be null when a version has no matching edit event.
Type-agnostic: pass any Modsable resource ID (Community, Collection,
Work). A resource with no MODS comes back as { "versions" => [] }.
Version labels are opaque, sortable OCFL vN strings — not a 1-based
counter — so treat them as identifiers to feed back into
mods_version, not as ordinals. The server admin-gates this endpoint
(it exposes edit attribution); 401 / 403 surface as raw Faraday
responses, matching history.
284 285 286 287 288 289 |
# File 'lib/atlas_rb/resource.rb', line 284 def self.mods_versions(id, nuid: nil, on_behalf_of: nil) AtlasRb::Mash.new(JSON.parse( connection({}, nuid, on_behalf_of: on_behalf_of) .get('/resources/' + id + '/mods/versions')&.body )) end |
.permissions(id, nuid: nil, on_behalf_of: nil) ⇒ Hash
Fetch the access-control entries for a resource.
175 176 177 178 179 180 |
# File 'lib/atlas_rb/resource.rb', line 175 def self.(id, nuid: nil, on_behalf_of: nil) AtlasRb::Mash.new(JSON.parse( connection({}, nuid, on_behalf_of: on_behalf_of) .get('/resources/' + id + '/permissions')&.body ))["resource"] end |
.preview(xml_path, nuid: nil, on_behalf_of: nil) ⇒ String
Validate a MODS XML document against Atlas's schema without persisting it.
Useful for surfacing validation errors in UIs before the user commits.
153 154 155 156 157 158 |
# File 'lib/atlas_rb/resource.rb', line 153 def self.preview(xml_path, nuid: nil, on_behalf_of: nil) payload = { binary: Faraday::Multipart::FilePart.new(File.open(xml_path), "application/xml", File.basename(xml_path)) } multipart(nuid, on_behalf_of: on_behalf_of).post('/resources/preview', payload)&.body end |