Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[HOLD] Create a set of local models #3453

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 24 additions & 0 deletions app/models/access_template.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
# frozen_string_literal: true

class AccessTemplate < ApplicationModel
define_attribute_methods :license, :copyright, :use_statement, :view, :download

attribute :license
attribute :copyright
attribute :use_statement
attribute :view
attribute :download

def initialize(cocina_model = Cocina::Models::AdminPolicyAccessTemplate.new)
super
end

# When the object is initialized, copy the properties from the cocina model to the entity:
def setup_properties!
self.license = model.license
self.copyright = model.copyright
self.use_statement = model.useAndReproductionStatement
self.view = model.view
self.download = model.download
end
end
36 changes: 36 additions & 0 deletions app/models/admin_policy.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
# frozen_string_literal: true

class AdminPolicy < ApplicationModel
define_attribute_methods :id, :version, :label, :admin_policy_id,
:registration_workflows, :collections_for_registration, :access_template, :roles

attribute :id
attribute :version
attribute :label
attribute :admin_policy_id
attribute :registration_workflows
attribute :collections_for_registration
attribute :access_template
attribute :roles

# When the object is initialized, copy the properties from the cocina model to the entity:
def setup_properties!
self.id = model.externalIdentifier
self.version = model.version
self.label = model.label
self.admin_policy_id = model.administrative.hasAdminPolicy
self.registration_workflows = model.administrative.registrationWorkflow
self.collections_for_registration = model.administrative.collectionsForRegistration
self.access_template = AccessTemplate.new(model.administrative.accessTemplate)
self.roles = model.administrative.roles
end

def save
raise 'not implemented'
# @model = AdminPolicyChangeSetPersister.update(model, self)
end

def self.model_name
::ActiveModel::Name.new(nil, nil, 'AdminPolicy')
end
end
31 changes: 31 additions & 0 deletions app/models/application_model.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
# frozen_string_literal: true

# @abstract
class ApplicationModel
include ActiveModel::Dirty
include ActiveModel::API

def self.attribute(name)
define_method name do
instance_variable_get(:"@#{name}")
end

define_method :"#{name}=" do |val|
send(:"#{name}_will_change!") unless val == instance_variable_get(:"@#{name}")
instance_variable_set(:"@#{name}", val)
end
end

def initialize(cocina = nil)
@model = cocina
setup_properties!
clear_changes_information
end

# The original cocina data
attr_reader :model

def persisted?
id.present?
end
end
39 changes: 39 additions & 0 deletions app/models/collection.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
# frozen_string_literal: true

class Collection < ApplicationModel
define_attribute_methods :id, :version, :admin_policy_id, :catkeys, :copyright,
:license, :source_id, :use_statement, :view_access

attribute :id
attribute :version
attribute :admin_policy_id
attribute :catkeys
attribute :copyright
attribute :license
attribute :source_id
attribute :use_statement
attribute :view_access

# When the object is initialized, copy the properties from the cocina model to the form:
def setup_properties!
self.id = model.externalIdentifier
self.version = model.version
self.admin_policy_id = model.administrative.hasAdminPolicy

self.catkeys = Catkey.symphony_links(model) if model.identification
self.copyright = model.access.copyright
self.use_statement = model.access.useAndReproductionStatement
self.license = model.access.license
self.source_id = model.identification&.sourceId

self.view_access = model.access.view
end

def save
@model = CollectionPersister.update(model, self)
end

def self.model_name
::ActiveModel::Name.new(nil, nil, 'Collection')
end
end
18 changes: 18 additions & 0 deletions app/models/embargo.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
# frozen_string_literal: true

class Embargo < ApplicationModel
define_attribute_methods :release_date, :view_access, :download_access, :access_location

attribute :release_date
attribute :view_access
attribute :download_access
attribute :access_location

# When the object is initialized, copy the properties from the cocina model to the entity:
def setup_properties!
self.release_date = model.releaseDate
self.view_access = model.view
self.download_access = model.download
self.access_location = model.location
end
end
21 changes: 21 additions & 0 deletions app/models/file_set.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
# frozen_string_literal: true

class FileSet < ApplicationModel
define_attribute_methods :files, :type, :label

attribute :files
attribute :type
attribute :label

# When the object is initialized, copy the properties from the cocina model to the entity:
def setup_properties!
self.type = model.type
self.label = model.label
self.files = model.structural.contains.map { |cocina| ManagedFile.new(cocina) }
end

# has the collection or any of its members changed?
def changed?
super || files.any?(&:changed?)
end
end
78 changes: 78 additions & 0 deletions app/models/item.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
# frozen_string_literal: true

class Item < ApplicationModel
define_attribute_methods :id, :version, :type, :admin_policy_id, :catkeys,
:collection_ids, :copyright, :embargo, :license,
:source_id, :use_statement, :barcode,
:view_access, :download_access, :access_location, :controlled_digital_lending,
:file_sets, :members, :release_tags

attribute :id
attribute :version
attribute :type
attribute :admin_policy_id
attribute :catkeys
attribute :collection_ids
attribute :copyright
attribute :embargo
attribute :license
attribute :source_id
attribute :use_statement
attribute :barcode
attribute :view_access
attribute :download_access
attribute :access_location
attribute :controlled_digital_lending
attribute :file_sets
attribute :members
attribute :release_tags

# When the object is initialized, copy the properties from the cocina model to the entity:
def setup_properties!
self.id = model.externalIdentifier
self.version = model.version
self.type = model.type
self.admin_policy_id = model.administrative.hasAdminPolicy

self.catkeys = Catkey.symphony_links(model)
self.barcode = model.identification.barcode
self.source_id = model.identification.sourceId

setup_acccess_properties!

self.collection_ids = Array(model.structural&.isMemberOf)
self.file_sets = model.structural.contains.map { |cocina| FileSet.new(cocina) }
self.members = Array(model.structural.hasMemberOrders&.first&.members)
self.release_tags = model.administrative.releaseTags
end

def setup_acccess_properties!
self.copyright = model.access.copyright
self.use_statement = model.access.useAndReproductionStatement
self.license = model.access.license

self.view_access = model.access.view
self.download_access = model.access.download
self.access_location = model.access.location
self.controlled_digital_lending = model.access.controlledDigitalLending
self.embargo = Embargo.new(model.access.embargo) if model.access.embargo
end

def save
@model = ItemPersister.update(model, self)
end

# This checks to see if the embargo or any of the properties of the embargo changed
def embargo_changed?
super || embargo&.changed?
end

# has the collection or any of its members changed?
def file_sets_changed?
super || file_sets.any?(&:changed?)
end

def self.model_name
::ActiveModel::Name.new(nil, nil, 'Item')
end
end
60 changes: 60 additions & 0 deletions app/models/managed_file.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
# frozen_string_literal: true

class ManagedFile < ApplicationModel
define_attribute_methods :view_access, :download_access, :access_location,
:controlled_digital_lending, :publish, :shelve, :preserve,
:filename, :mime_type, :size, :use, :height, :width

attribute :view_access
attribute :download_access
attribute :access_location
attribute :controlled_digital_lending
attribute :publish
attribute :shelve
attribute :preserve
attribute :filename
attribute :mime_type
attribute :size
attribute :use
attribute :height
attribute :width

# When the object is initialized, copy the properties from the cocina model to the entity:
def setup_properties!
self.filename = model.filename
self.mime_type = model.hasMimeType
self.size = model.size
self.use = model.use

self.view_access = model.access.view
self.download_access = model.access.download
self.access_location = model.access.location
self.controlled_digital_lending = model.access.controlledDigitalLending

self.publish = model.administrative.publish
self.shelve = model.administrative.shelve
self.preserve = model.administrative.sdrPreserve

self.height = model.presentation&.height
self.width = model.presentation&.width
end

def administrative_changed?
publish_changed? || shelve_changed? || preserve_changed?
end

# Assigns the correct access and ensures publsh and shelve are false
def dark!
citation_only!
self.publish = false
self.shelve = false
end

# Assigns the correct access so the object shows on PURL, but doesn't reveal any files
def citation_only!
self.view_access = 'dark'
self.download_access = 'none'
self.controlled_digital_lending = false
self.access_location = nil
end
end
74 changes: 74 additions & 0 deletions app/services/collection_persister.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
# frozen_string_literal: true

# Writes updates to Cocina collections
class CollectionPersister
# @param [Cocina::Models::Collection] model the orignal state of the collection
# @param [Collection] change_set the values to update.
# @return [Cocina::Models::Collection] the model with updates applied
def self.update(model, change_set)
new(model, change_set).update
end

def initialize(model, change_set)
@model = model
@change_set = change_set
end

def update
updated_model = update_identification(model)
.then { |updated| updated_access(updated) }
.then { |updated| updated_administrative(updated) }

Repository.store(updated_model)
end

private

# The map between the change set fields and the Cocina field names
ACCESS_FIELDS = {
copyright: :copyright,
license: :license,
use_statement: :useAndReproductionStatement,
view_access: :access
}.freeze

attr_reader :model, :change_set

delegate :admin_policy_id, :catkeys, *ACCESS_FIELDS.keys,
:source_id_changed?, :catkeys_changed?, :admin_policy_id_changed?,
:copyright_changed?, :license_changed?, :use_statement_changed?,
:view_access_changed?, to: :change_set

def access_changed?
ACCESS_FIELDS.keys.any? { |field| public_send("#{field}_changed?") }
end

def updated_access(updated)
return updated unless access_changed?

updated.new(access: updated.access.new(updated_access_properties))
end

def updated_access_properties
{}.tap do |access_properties|
ACCESS_FIELDS.each do |field, cocina_field|
access_properties[cocina_field] = public_send(field).presence if public_send("#{field}_changed?")
end
end
end

def update_identification(updated)
return updated unless source_id_changed? || catkeys_changed?

identification_props = updated.identification&.to_h || {}
identification_props[:catalogLinks] = Catkey.serialize(model, catkeys) if catkeys_changed?
updated.new(identification: identification_props.compact.presence)
end

def updated_administrative(updated)
return updated unless admin_policy_id_changed?

updated_administrative = updated.administrative.new(hasAdminPolicy: admin_policy_id)
updated.new(administrative: updated_administrative)
end
end
Loading