diff --git a/app/models/hyrax/flexible_schema.rb b/app/models/hyrax/flexible_schema.rb index 428978d7b1..b68d1ee688 100644 --- a/app/models/hyrax/flexible_schema.rb +++ b/app/models/hyrax/flexible_schema.rb @@ -11,17 +11,24 @@ def class_names profile['classes'].keys.each do |class_name| @class_names[class_name] = {} end - profile['properties'].each do |key, value| - value['available_on']['class'].each do |property_class| + profile['properties'].each do |key, values| + values['available_on']['class'].each do |property_class| # map some m3 items to what Hyrax expects - value['type'] = lookup_type(value['range']) - value['predicate'] = value['property_uri'] - @class_names[property_class][key] = value + values = values_map(values) + @class_names[property_class][key] = values end end @class_names end + def values_map(values) + values['type'] = lookup_type(value['range']) + values['predicate'] = value['property_uri'] + values['index_keys'] = values['indexing'] + values['multiple'] = values['multi_value'] + values + end + def lookup_type(range) case range when "http://www.w3.org/2001/XMLSchema#dateTime" diff --git a/app/services/hyrax/m3_schema_loader.rb b/app/services/hyrax/m3_schema_loader.rb index 094723fcbe..25554b81f5 100644 --- a/app/services/hyrax/m3_schema_loader.rb +++ b/app/services/hyrax/m3_schema_loader.rb @@ -7,125 +7,7 @@ module Hyrax # Read m3 profiles from the database # # @see config/metadata/m3_profile.yaml for an example configuration - class M3SchemaLoader - ## - # @param [Symbol] schema - # - # @return [Hash] a map from attribute names to - # types - def attributes_for(schema:, version: 1) - definitions(schema, version).each_with_object({}) do |definition, hash| - hash[definition.name] = definition.type.meta(definition.config) - end - end - - ## - # @param [Symbol] schema - # - # @return [Hash{Symbol => Hash{Symbol => Object}}] - def form_definitions_for(schema:, version: 1) - definitions(schema, version).each_with_object({}) do |definition, hash| - next if definition.form_options.empty? - - hash[definition.name] = definition.form_options - end - end - - ## - # @param [Symbol] schema - # - # @return [{Symbol => Symbol}] a map from index keys to attribute names - def index_rules_for(schema:, version: 1) - definitions(schema, version).each_with_object({}) do |definition, hash| - definition.index_keys.each do |key| - hash[key] = definition.name - end - end - end - - ## - # @api private - class AttributeDefinition - ## - # @!attr_reader :config - # @return [Hash] - # @!attr_reader :name - # @return [#to_sym] - attr_reader :config, :name - - ## - # @param [#to_sym] name - # @param [Hash] config - def initialize(name, config) - @config = config - @name = name.to_sym - end - - ## - # @return [Hash{Symbol => Object}] - def form_options - config.fetch('form', {}).symbolize_keys - end - - ## - # @return [Enumerable] - def index_keys - config.fetch('indexing', []).map(&:to_sym) - end - - ## - # @return [Dry::Types::Type] - def type - collection_type = if config['multi_value'] - Valkyrie::Types::Array.constructor { |v| Array(v).select(&:present?) } - else - Identity - end - collection_type.of(type_for(config['type'])) - end - - ## - # @api private - # - # This class acts as a Valkyrie/Dry::Types collection with typed members, - # but instead of wrapping the given type with itself as the collection type - # (as in `Valkyrie::Types::Array.of(MyType)`), it returns the given type. - # - # @example - # Identity.of(Valkyrie::Types::String) # => Valkyrie::Types::String - # - class Identity - ## - # @param [Dry::Types::Type] - # @return [Dry::Types::Type] the type passed in - def self.of(type) - type - end - end - - private - - ## - # Maps a configuration string value to a `Valkyrie::Type`. - # - # @param [String] - # @return [Dry::Types::Type] - def type_for(type) - case type - when 'id' - Valkyrie::Types::ID - when 'uri' - Valkyrie::Types::URI - when 'date_time' - Valkyrie::Types::DateTime - else - "Valkyrie::Types::#{type.capitalize}".constantize - end - end - end - - class UndefinedSchemaError < ArgumentError; end - + class M3SchemaLoader < Hyrax::SchemaLoader private ## diff --git a/app/services/hyrax/schema_loader.rb b/app/services/hyrax/schema_loader.rb new file mode 100644 index 0000000000..73728795db --- /dev/null +++ b/app/services/hyrax/schema_loader.rb @@ -0,0 +1,130 @@ +# frozen_string_literal: true + +module Hyrax + ## + # @api private + # + # This is a simple yaml config-driven schema loader + # + # @see config/metadata/basic_metadata.yaml for an example configuration + class SchemaLoader + ## + # @param [Symbol] schema + # + # @return [Hash] a map from attribute names to + # types + def attributes_for(schema:, version: 1) + definitions(schema).each_with_object({}) do |definition, hash| + hash[definition.name] = definition.type.meta(definition.config) + end + end + + ## + # @param [Symbol] schema + # + # @return [Hash{Symbol => Hash{Symbol => Object}}] + def form_definitions_for(schema:, version: 1) + definitions(schema).each_with_object({}) do |definition, hash| + next if definition.form_options.empty? + + hash[definition.name] = definition.form_options + end + end + + ## + # @param [Symbol] schema + # + # @return [{Symbol => Symbol}] a map from index keys to attribute names + def index_rules_for(schema:, version: 1) + definitions(schema).each_with_object({}) do |definition, hash| + definition.index_keys.each do |key| + hash[key] = definition.name + end + end + end + + ## + # @api private + class AttributeDefinition + ## + # @!attr_reader :config + # @return [Hash] + # @!attr_reader :name + # @return [#to_sym] + attr_reader :config, :name + + ## + # @param [#to_sym] name + # @param [Hash] config + def initialize(name, config) + @config = config + @name = name.to_sym + end + + ## + # @return [Hash{Symbol => Object}] + def form_options + config.fetch('form', {}).symbolize_keys + end + + ## + # @return [Enumerable] + def index_keys + config.fetch('index_keys', []).map(&:to_sym) + end + + ## + # @return [Dry::Types::Type] + def type + collection_type = if config['multiple'] + Valkyrie::Types::Array.constructor { |v| Array(v).select(&:present?) } + else + Identity + end + collection_type.of(type_for(config['type'])) + end + + ## + # @api private + # + # This class acts as a Valkyrie/Dry::Types collection with typed members, + # but instead of wrapping the given type with itself as the collection type + # (as in `Valkyrie::Types::Array.of(MyType)`), it returns the given type. + # + # @example + # Identity.of(Valkyrie::Types::String) # => Valkyrie::Types::String + # + class Identity + ## + # @param [Dry::Types::Type] + # @return [Dry::Types::Type] the type passed in + def self.of(type) + type + end + end + + private + + ## + # Maps a configuration string value to a `Valkyrie::Type`. + # + # @param [String] + # @return [Dry::Types::Type] + def type_for(type) + case type + when 'id' + Valkyrie::Types::ID + when 'uri' + Valkyrie::Types::URI + when 'date_time' + Valkyrie::Types::DateTime + else + "Valkyrie::Types::#{type.capitalize}".constantize + end + end + end + + class UndefinedSchemaError < ArgumentError; end + + end +end diff --git a/app/services/hyrax/simple_schema_loader.rb b/app/services/hyrax/simple_schema_loader.rb index f9c8a1b5a6..eba090961c 100644 --- a/app/services/hyrax/simple_schema_loader.rb +++ b/app/services/hyrax/simple_schema_loader.rb @@ -7,129 +7,13 @@ module Hyrax # This is a simple yaml config-driven schema loader # # @see config/metadata/basic_metadata.yaml for an example configuration - class SimpleSchemaLoader - ## - # @param [Symbol] schema - # - # @return [Hash] a map from attribute names to - # types - def attributes_for(schema:, version: 1) - definitions(schema).each_with_object({}) do |definition, hash| - hash[definition.name] = definition.type.meta(definition.config) - end - end - - ## - # @param [Symbol] schema - # - # @return [Hash{Symbol => Hash{Symbol => Object}}] - def form_definitions_for(schema:, version: 1) - definitions(schema).each_with_object({}) do |definition, hash| - next if definition.form_options.empty? - - hash[definition.name] = definition.form_options - end - end - - ## - # @param [Symbol] schema - # - # @return [{Symbol => Symbol}] a map from index keys to attribute names - def index_rules_for(schema:, version: 1) - definitions(schema).each_with_object({}) do |definition, hash| - definition.index_keys.each do |key| - hash[key] = definition.name - end - end - end - + class SimpleSchemaLoader < Hyrax::SchemaLoader def permissive_schema_for_valkrie_adapter metadata_files.each_with_object({}) do |schema_name, ret_hsh| predicate_pairs(ret_hsh, schema_name) end end - ## - # @api private - class AttributeDefinition - ## - # @!attr_reader :config - # @return [Hash] - # @!attr_reader :name - # @return [#to_sym] - attr_reader :config, :name - - ## - # @param [#to_sym] name - # @param [Hash] config - def initialize(name, config) - @config = config - @name = name.to_sym - end - - ## - # @return [Hash{Symbol => Object}] - def form_options - config.fetch('form', {}).symbolize_keys - end - - ## - # @return [Enumerable] - def index_keys - config.fetch('index_keys', []).map(&:to_sym) - end - - ## - # @return [Dry::Types::Type] - def type - collection_type = if config['multiple'] - Valkyrie::Types::Array.constructor { |v| Array(v).select(&:present?) } - else - Identity - end - collection_type.of(type_for(config['type'])) - end - - ## - # @api private - # - # This class acts as a Valkyrie/Dry::Types collection with typed members, - # but instead of wrapping the given type with itself as the collection type - # (as in `Valkyrie::Types::Array.of(MyType)`), it returns the given type. - # - # @example - # Identity.of(Valkyrie::Types::String) # => Valkyrie::Types::String - # - class Identity - ## - # @param [Dry::Types::Type] - # @return [Dry::Types::Type] the type passed in - def self.of(type) - type - end - end - - private - - ## - # Maps a configuration string value to a `Valkyrie::Type`. - # - # @param [String] - # @return [Dry::Types::Type] - def type_for(type) - case type - when 'id' - Valkyrie::Types::ID - when 'uri' - Valkyrie::Types::URI - when 'date_time' - Valkyrie::Types::DateTime - else - "Valkyrie::Types::#{type.capitalize}".constantize - end - end - end - class UndefinedSchemaError < ArgumentError; end private @@ -180,9 +64,9 @@ def predicate_pairs(ret_hsh, schema_name) def multiple_predicate_message(name, existing, incoming) message = "The attribute of #{name} has been assigned a predicate multiple times " \ - "within the metadata YAMLs. Please be aware that once the attribute's " \ - "predicate value is first assigned, any other value will be ignored. " \ - "The existing value is #{existing} preventing the use of #{incoming}" + "within the metadata YAMLs. Please be aware that once the attribute's " \ + "predicate value is first assigned, any other value will be ignored. " \ + "The existing value is #{existing} preventing the use of #{incoming}" Hyrax.logger.warn(message) end end