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

Parameters:

  • ancestors (WashoutType)

    The class that inherits from WashoutType

Returns:

  • (Hash)

    A hash that has as a key the class name in downcase letters and as value the mapping of the class attributes

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

Parameters:

  • defined (Array<Hash>)

    Array that is used for checking if a complex type is already defined

  • complex_class (Class)

    the complex type name used for searching

Returns:

  • (Boolean)

    returns true or false if the complex type is found inside the array

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

Parameters:

  • config (WashOut::SoapConfig)

    the configuration of the soap service

  • complex_class (Clas)

    the complex type name of the object

  • defined (Array<Hash>)

    An array that holds all the complex types found so far

Returns:

  • (Array<Class>, nil)

    returns nil if object not classified othewise an array of classes that are ancestors to curent object

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

Parameters:

  • config (WashOut::SoapConfig)

    an object that holds the soap configuration

  • defined (Array<Hash>)

    An Array with all the complex types that have been detected till now

Returns:

  • (Array<Hash>)

    An array with all the complex types that

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

Parameters:

  • class_name (Class)

    The name of the class

  • object (WashOut::Param)

    The object itself

  • ancestors (Array<Class>)

    An array with all the ancestors that the object inherits from

Returns:

  • (Hash)

    A hash with that contains the params sent to the method


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

Parameters:

  • complex_class (String)

    A string that contains the name of a class

Returns:

  • (Class, nil)

    returns the class if it is defined otherwise nil


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

Parameters:

  • defined (Array) (defaults to: [])

    Array that is used for when iterating through descendants and ancestors

Returns:

  • (Class)

    the complex type name of the current object

See Also:


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.

Returns:

  • (Hash)

    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

Parameters:

  • config (WashOut::SoapConfig)

    an object that holds the soap configuration

  • complex_class (Class, String)

    the name of the complex type either as a string or a class

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'

Parameters:

  • class_name (Class, String)

    the name of the on object that is used to fetch his ancestors

Returns:

  • (Array<Class>)

    Returns an array with all the classes from each the object inherits from but filters the results and removes the classes 'ActiveRecord::Base', 'Object', 'BasicObject', 'WashOut::Type'

See Also:


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)

Parameters:

  • config (WashOut::SoapConfig)

    holds the soap configuration

  • class_name (Class)

    The name of the class that is used for fetching the ancestors

  • defined (Array<Hash>)

    An Array with all the complex types that have been detected so far

Returns:

  • (Array<Class>)

    An Array of classes from which the class that is sent as parameter inherits from

See Also:


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

Parameters:

  • config (WashOut::SoapConfig)

    holds the soap configuration

  • defined (Array<Hash>)

    An array with all the complex type structures that have been detected so far

Returns:

  • (Array<Hash>)

    An array with all the complex type that have been detected while iterating to all the descendants of the current object and also contains the previous ones

See Also:


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

Parameters:

  • keys (Array<String>)

    An array with the keys that need to be removed from current object


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

Parameters:

  • ancestor (WasOut::Param)

    The complex type that is used to compare to the current complex type

Returns:

  • (Boolean)

    returns true if both objects have same structure, otherwise will first remove the inheritated elements from his ancestor and then return false

See Also:


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