Module: WashoutBuilder::Document::ComplexType

Extended by:
ActiveSupport::Concern
Includes:
SharedComplexType
Defined in:
lib/washout_builder/document/complex_type.rb

Overview

class that is used for current Washout::Param object to know his complex type name and structure and detect ancestors and descendants

Instance Method Summary collapse

Methods included from SharedComplexType

#get_complex_type_ancestors

Instance Method Details

#ancestor_structure(ancestors) ⇒ Hash

method that constructs the a hash with the name of the ancestor ( the class name) and as value its elemen structure

See Also:

  • WashOut::Type#wash_out_param_map

189
190
191
# File 'lib/washout_builder/document/complex_type.rb', line 189

def ancestor_structure(ancestors)
  { ancestors[0].to_s.downcase => ancestors[0].wash_out_param_map }
end

#check_duplicate_complex_class(defined, complex_class) ⇒ Boolean

checks if the complex class appears in the array of complex types

Raises:

  • (RuntimeError)

    Raises a runtime error if is detected a duplicate use of the complex type


32
33
34
35
# File 'lib/washout_builder/document/complex_type.rb', line 32

def check_duplicate_complex_class(defined, complex_class)
  complex_obj_found = defined.find { |hash| hash[:class] == complex_class }
  raise "Duplicate use of `#{basic_type}` type name. Consider using classified types." if !complex_obj_found.nil? && struct? && !classified?
end

#complex_type_ancestors(config, complex_class, defined) ⇒ Array<Class>?

finds the complex class ancestors if the current object is classified, otherwise returns nil

See Also:


48
49
50
# File 'lib/washout_builder/document/complex_type.rb', line 48

def complex_type_ancestors(config, complex_class, defined)
  classified? ? get_class_ancestors(config, complex_class, defined) : nil
end

#complex_type_descendants(config, defined) ⇒ Array<Hash>

Method used to fetch the descendants of the current object

See Also:


152
153
154
155
156
157
158
159
# File 'lib/washout_builder/document/complex_type.rb', line 152

def complex_type_descendants(config, defined)
  if struct?
    c_names = []
    map.each { |obj| c_names.concat(obj.get_nested_complex_types(config, defined)) }
    defined.concat(c_names)
  end
  defined
end

#complex_type_hash(class_name, object, ancestors) ⇒ Hash

Constructs the complex type information wuth its name, with the object itself and his ancestors


200
201
202
203
204
205
206
# File 'lib/washout_builder/document/complex_type.rb', line 200

def complex_type_hash(class_name, object, ancestors)
  {
    class: class_name,
    obj: object,
    ancestors: ancestors
  }
end

#find_class_from_string(complex_class) ⇒ Class?

Description of method


99
100
101
102
103
# File 'lib/washout_builder/document/complex_type.rb', line 99

def find_class_from_string(complex_class)
  complex_class.is_a?(Class) ? complex_class : complex_class.constantize
rescue
  nil
end

#find_complex_class_name(defined = []) ⇒ Class

finds the complex class name of the current Washout::Param object and checks if is a duplicate


18
19
20
21
22
# File 'lib/washout_builder/document/complex_type.rb', line 18

def find_complex_class_name(defined = [])
  complex_class = struct? ? basic_type.tr('.', '/').camelize : nil
  check_duplicate_complex_class(defined, complex_class) unless complex_class.nil? || defined.blank?
  complex_class
end

#find_param_structureHash

Returns THe hash that contains information about the structure of the current object as complex type


57
58
59
60
61
62
# File 'lib/washout_builder/document/complex_type.rb', line 57

def find_param_structure
  map.each_with_object({}) do|item, memo|
    memo[item.name] = item.type
    memo
  end
end

#fix_descendant_wash_out_type(config, complex_class) ⇒ void

This method returns an undefined value.

Dirty hack to fix the first washout param type. This only applies if the first complex type is inheriting WashOutType its name should be set to its descendant and the map of the current object will be set to its descendant

See Also:

  • WashOut::Param#parse_builder_def

83
84
85
86
87
88
89
90
91
92
# File 'lib/washout_builder/document/complex_type.rb', line 83

def fix_descendant_wash_out_type(config, complex_class)
  param_class = find_class_from_string(complex_class)
  base_param_class = WashoutBuilder::Type.base_param_class
  base_type_class =  WashoutBuilder::Type.base_type_class
  return if base_param_class.blank? || base_type_class.blank?
  return unless param_class.present? && param_class.ancestors.include?(base_type_class) && map[0].present?
  descendant = base_param_class.parse_builder_def(config, param_class.wash_out_param_map)[0]
  self.name = descendant.name
  self.map = descendant.map
end

#get_ancestors(class_name) ⇒ Array<Class>

Mehod that is used to get the ancestors of the current complex type the method will not filter the results by rejecting the classes 'ActiveRecord::Base', 'Object', 'BasicObject', 'WashOut::Type'


132
133
134
135
136
137
138
139
140
141
142
# File 'lib/washout_builder/document/complex_type.rb', line 132

def get_ancestors(class_name)
  param_class = find_class_from_string(class_name)
  if param_class.nil?
    return nil
  else
    base_type_class =  WashoutBuilder::Type.base_type_class
    filtered_classes = ['ActiveRecord::Base', 'Object', 'BasicObject']
    filtered_classes << base_type_class.to_s if base_type_class.present?
    get_complex_type_ancestors(param_class, filtered_classes)
  end
end

#get_class_ancestors(config, class_name, defined) ⇒ Array<Class>

A recursive method that fetches the ancestors of a given class (that inherits from WashoutType)


219
220
221
222
223
224
225
226
227
228
229
230
231
# File 'lib/washout_builder/document/complex_type.rb', line 219

def get_class_ancestors(config, class_name, defined)
  ancestors = get_ancestors(class_name)
  return if ancestors.blank?
  base_param_class = WashoutBuilder::Type.base_param_class
  return if base_param_class.blank?
  ancestor_object = base_param_class.parse_def(config, ancestor_structure(ancestors))[0]
  bool_the_same = same_structure_as_ancestor?(ancestor_object)
  unless bool_the_same
    top_ancestors = get_class_ancestors(config, ancestors[0], defined)
    defined << complex_type_hash(ancestors[0], ancestor_object, top_ancestors)
  end
  ancestors unless bool_the_same
end

#get_nested_complex_types(config, defined) ⇒ Array<Hash>

Recursive method that tries to identify all the nested descendants of the current object


172
173
174
175
176
177
178
179
180
181
# File 'lib/washout_builder/document/complex_type.rb', line 172

def get_nested_complex_types(config, defined)
  defined = [] if defined.blank?
  complex_class = find_complex_class_name(defined)
  fix_descendant_wash_out_type(config, complex_class)
  unless complex_class.nil?
    defined << complex_type_hash(complex_class, self, complex_type_ancestors(config, complex_class, defined))
  end
  defined = complex_type_descendants(config, defined)
  defined.blank? ? [] : defined.sort_by { |hash| hash[:class].to_s.downcase }.uniq
end

#remove_type_inheritable_elements(keys) ⇒ void

This method returns an undefined value.

removes from this current object the elements that are inherited from other objects and set the map of the curent object to the new value


70
71
72
# File 'lib/washout_builder/document/complex_type.rb', line 70

def remove_type_inheritable_elements(keys)
  self.map = map.delete_if { |element| keys.include?(element.name) }
end

#same_structure_as_ancestor?(ancestor) ⇒ Boolean

Method that is used to check if the current object has exactly same structure as one of his ancestors if it is true, will return true, otherwise will first remove the inheritated elements from his ancestor and then return false


113
114
115
116
117
118
119
120
121
122
# File 'lib/washout_builder/document/complex_type.rb', line 113

def same_structure_as_ancestor?(ancestor)
  param_structure = find_param_structure
  ancestor_structure = ancestor.find_param_structure
  if param_structure.keys == ancestor_structure.keys
    return true
  else
    remove_type_inheritable_elements(ancestor_structure.keys)
    return false
  end
end