RecursiveNormalizer.normalize()   A
last analyzed

Complexity

Conditions 2

Size

Total Lines 13

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 0
loc 13
rs 9.4285
cc 2
1
# frozen_string_literal: true
2
3
require_relative '../type'
4
require_relative '../type/analyzer'
5
6
module AMA
7
  module Entity
8
    class Mapper
9
      class Engine
10
        # Helper and self-explanatory engine class
11
        class RecursiveNormalizer
12
          # @param [AMA::Entity::Mapper::Type::Registry] registry
13
          def initialize(registry)
14
            @registry = registry
15
          end
16
17
          # @param [Object] entity
18
          # @param [AMA::Entity::Mapper::Context] ctx
19
          # @param [AMA::Entity::Mapper::Type, NilClass] type
20
          def normalize(entity, ctx, type = nil)
21
            type ||= find_type(entity.class)
22
            target = entity
23
            ctx.logger.debug("Normalizing #{entity.class} as #{type.type}")
24
            if type.virtual
25
              message = "Type #{type.type} is virtual, skipping to attributes"
26
              ctx.logger.debug(message)
27
            else
28
              target = type.normalizer.normalize(entity, type, ctx)
29
            end
30
            target_type = find_type(target.class)
31
            process_attributes(target, target_type, ctx)
32
          end
33
34
          private
35
36
          # @param [Object] entity
37
          # @param [AMA::Entity::Mapper::Type] type
38
          # @param [AMA::Entity::Mapper::Context] ctx
39
          def process_attributes(entity, type, ctx)
40
            if type.attributes.empty?
41
              message = "No attributes found on #{type.type}, returning " \
42
                "#{entity.class} as is"
43
              ctx.logger.debug(message)
44
              return entity
45
            end
46
            normalize_attributes(entity, type, ctx)
47
          end
48
49
          # @param [Object] entity
50
          # @param [AMA::Entity::Mapper::Type] type
51
          # @param [AMA::Entity::Mapper::Context] ctx
52
          def normalize_attributes(entity, type, ctx)
53
            message = "Normalizing attributes of #{entity.class} " \
54
              "(as #{type.type})"
55
            ctx.logger.debug(message)
56
            enumerator = type.enumerator.enumerate(entity, type, ctx)
57
            enumerator.each do |attribute, value, segment|
58
              local_ctx = ctx.advance(segment)
59
              value = normalize(value, local_ctx)
60
              type.injector.inject(entity, type, attribute, value, local_ctx)
61
            end
62
            entity
63
          end
64
65
          # @param [Class, Module] klass
66
          # @return [AMA::Entity::Mapper::Type]
67
          def find_type(klass)
68
            @registry.find(klass) || Type::Analyzer.analyze(klass)
69
          end
70
        end
71
      end
72
    end
73
  end
74
end
75