diff --git a/lib/cocina/models/contributor.rb b/lib/cocina/models/contributor.rb index cdc8d262..badad808 100644 --- a/lib/cocina/models/contributor.rb +++ b/lib/cocina/models/contributor.rb @@ -14,6 +14,7 @@ class Contributor < Struct attribute :note, Types::Strict::Array.of(DescriptiveValue).default([].freeze) # URL or other pointer to the location of the contributor information. attribute? :valueAt, Types::Strict::String + attribute :parallelContributor, Types::Strict::Array.of(DescriptiveParallelContributor).default([].freeze) end end end diff --git a/lib/cocina/models/description.rb b/lib/cocina/models/description.rb index db227ebd..6581ba44 100644 --- a/lib/cocina/models/description.rb +++ b/lib/cocina/models/description.rb @@ -20,7 +20,7 @@ class Description < Struct attribute? :adminMetadata, DescriptiveAdminMetadata.optional # URL or other pointer to the location of the resource description. attribute? :valueAt, Types::Strict::String - # Stanford persistent URL associated with the related resource. + # Stanford persistent URL associated with the related resource. Note this is http, not https. attribute :purl, Types::Strict::String end end diff --git a/lib/cocina/models/descriptive_parallel_contributor.rb b/lib/cocina/models/descriptive_parallel_contributor.rb new file mode 100644 index 00000000..b9c46941 --- /dev/null +++ b/lib/cocina/models/descriptive_parallel_contributor.rb @@ -0,0 +1,21 @@ +# frozen_string_literal: true + +module Cocina + module Models + # DEPRECATED + # Value model for multiple representations of information about the same contributor (e.g. in different languages). + class DescriptiveParallelContributor < Struct + attribute :name, Types::Strict::Array.of(DescriptiveValue).default([].freeze) + # Entity type of the contributor (person, organization, etc.). See https://github.com/sul-dlss/cocina-models/blob/main/docs/description_types.md for valid types. + attribute? :type, Types::Strict::String + # Status of the contributor relative to other parallel contributors (e.g. the primary author among a group of contributors). + attribute? :status, Types::Strict::String + attribute :role, Types::Strict::Array.of(DescriptiveValue).default([].freeze) + attribute :identifier, Types::Strict::Array.of(DescriptiveValue).default([].freeze) + attribute :note, Types::Strict::Array.of(DescriptiveValue).default([].freeze) + # URL or other pointer to the location of the contributor information. + attribute? :valueAt, Types::Strict::String + attribute? :valueLanguage, DescriptiveValueLanguage.optional + end + end +end diff --git a/lib/cocina/models/related_resource.rb b/lib/cocina/models/related_resource.rb index b7921017..2f1a38c3 100644 --- a/lib/cocina/models/related_resource.rb +++ b/lib/cocina/models/related_resource.rb @@ -19,7 +19,7 @@ class RelatedResource < Struct attribute :identifier, Types::Strict::Array.of(DescriptiveValue).default([].freeze) attribute? :standard, Standard.optional attribute :subject, Types::Strict::Array.of(DescriptiveValue).default([].freeze) - # Stanford persistent URL associated with the related resource. + # Stanford persistent URL associated with the related resource. Note this is http, not https. attribute? :purl, Types::Strict::String attribute? :access, DescriptiveAccessMetadata.optional attribute :relatedResource, Types::Strict::Array.of(RelatedResource).default([].freeze) diff --git a/lib/cocina/models/validators/description_types_validator.rb b/lib/cocina/models/validators/description_types_validator.rb index aa7bf657..7f997dee 100644 --- a/lib/cocina/models/validators/description_types_validator.rb +++ b/lib/cocina/models/validators/description_types_validator.rb @@ -71,7 +71,7 @@ def match?(path, type_signature) # Some part of the path are ignored for the purpose of matching. def clean_path(path) new_path = path.reject do |part| - part.is_a?(Integer) || %i[parallelValue parallelEvent].include?(part) + part.is_a?(Integer) || %i[parallelValue parallelContributor parallelEvent].include?(part) end # This needs to happen after parallelValue is removed # to handle structuredValue > parallelValue > structuredValue diff --git a/openapi.yml b/openapi.yml index 3318ee9b..e30ec7d5 100644 --- a/openapi.yml +++ b/openapi.yml @@ -549,6 +549,11 @@ components: valueAt: description: URL or other pointer to the location of the contributor information. type: string + parallelContributor: + description: For multiple representations of information about the same contributor (e.g. in different languages). + type: array + items: + $ref: "#/components/schemas/DescriptiveParallelContributor" ControlledDigitalLendingAccess: type: object properties: @@ -772,6 +777,44 @@ components: type: array items: $ref: "#/components/schemas/DescriptiveValue" + DescriptiveParallelContributor: + description: Value model for multiple representations of information about the same contributor (e.g. in different languages). + deprecated: true + type: object + additionalProperties: false + properties: + name: + description: Names associated with a contributor. + type: array + items: + $ref: "#/components/schemas/DescriptiveValue" + type: + description: Entity type of the contributor (person, organization, etc.). See https://github.com/sul-dlss/cocina-models/blob/main/docs/description_types.md for valid types. + type: string + status: + description: Status of the contributor relative to other parallel contributors (e.g. the primary author among a group of contributors). + type: string + role: + description: Relationships of the contributor to the resource or to an event in its history. + type: array + items: + $ref: "#/components/schemas/DescriptiveValue" + identifier: + description: Identifiers and URIs associated with the contributor entity. + type: array + items: + $ref: "#/components/schemas/DescriptiveValue" + note: + description: Other information associated with the contributor. + type: array + items: + $ref: "#/components/schemas/DescriptiveValue" + valueAt: + description: URL or other pointer to the location of the contributor information. + type: string + valueLanguage: + # description: Language of the descriptive element value + $ref: "#/components/schemas/DescriptiveValueLanguage" DescriptiveParallelEvent: description: Value model for multiple representations of information about the same event (e.g. in different languages). type: object diff --git a/spec/cocina/models/validators/description_types_validator_spec.rb b/spec/cocina/models/validators/description_types_validator_spec.rb index c6e4d4ab..9080f304 100644 --- a/spec/cocina/models/validators/description_types_validator_spec.rb +++ b/spec/cocina/models/validators/description_types_validator_spec.rb @@ -256,6 +256,92 @@ end end + describe 'with an invalid parallelContributor' do + let(:desc_props) do + { + contributor: [ + { + parallelContributor: [ + { + name: [ + { + structuredValue: [ + { + value: 'Li, Yahong', + type: 'foo' + }, + { + value: '1963-', + type: 'life dates' + } + ] + } + ] + }, + { + name: [ + { + value: '李亞虹' + } + ] + } + ], + type: 'person' + } + ] + } + end + + it 'ignores parallelContributor and raises' do + expect do + validate + end.to raise_error(Cocina::Models::ValidationError, + 'Unrecognized types in description: ' \ + 'contributor1.parallelContributor1.name1.structuredValue1 (foo)') + end + end + + describe 'with an valid parallelContributor' do + let(:desc_props) do + { + contributor: [ + { + parallelContributor: [ + { + name: [ + { + structuredValue: [ + { + value: 'Li, Yahong', + type: 'name' + }, + { + value: '1963-', + type: 'life dates' + } + ] + } + ] + }, + { + name: [ + { + value: '李亞虹' + } + ] + } + ], + type: 'person' + } + ] + } + end + + it 'ignores parallelContributor and does not raise' do + expect { validate }.not_to raise_error + end + end + describe 'with a nested structuredValue' do let(:desc_props) do {