module PowerStencil module CommandProcessors module EntityHelper EntitySearchReference = Struct.new(:type, :name) do def as_path [type, name].map(&:to_s).join '/' end end def describe_entity_types(entity_types) report = {} project.engine.available_entity_types.each { |entity_type| report = build_entity_type_report entity_type, report } scoped_classes = report.keys report.select{|klass, _| entity_types.include? klass.entity_type} .sort_by {|klass, _| klass.entity_type.to_s} .each do |klass, info| puts '-' * 80 puts "=> #{klass.entity_type} (class: #{klass.name})" puts " - PARENT ENTITY TYPE: #{klass.superclass.entity_type}" if scoped_classes.include? klass.superclass unless info[:fields].empty? puts ' - FIELDS:' info[:fields].each do |field_name, constraints| if constraints.empty? puts " - #{field_name}" else puts " - #{field_name}:" constraints.each do |name, value| puts " - #{name}: #{value}" end end end end unless info[:methods].empty? puts ' - METHODS:' info[:methods].each do |method_name, _| puts " - #{method_name}" end end unless info[:special_methods].empty? puts ' - SPECIAL METHODS:' info[:special_methods].each do |method_name, method_info| puts " - #{method_name} (reverse method defined from relation '#{method_info[:source_field]}' in entity type '#{method_info[:source_entity]}')" end end end end def display_entity(entity) puts_and_logs "# Entity '#{entity.name}' (#{entity.type})" if config[:'names-only'] puts "- '#{entity.as_path}' ('#{entity.name}' of the type '#{entity.type}')" else if config[:raw] puts entity.to_yaml else # Display entity including data coming from reverse methods h = entity.to_hash entity.class.fields_constraints.each do |_, constraints| next unless constraints[:reverse_method] reverse_method_conf = constraints[:reverse_method] val = entity.send(reverse_method_conf[:actual_method]) next if val.nil? next if val.is_a? Array and val.empty? node = h[entity.class.name][:dynamic_data] ||= {} node[reverse_method_conf[:actual_method]] = case val when Array val.map &:to_reference else val.to_reference end end puts h.to_yaml end puts end end def targets_from_criteria(search_criteria, universe) target_universe = if config[:compiled] universe.compile scenario: config[:scenario] else universe end if config[:regexp] target_universe.get_entities do |entity| id = entity.as_path keep = false search_criteria.each do |criterion| if md = id.match(/#{criterion}/i) keep = true break end end keep end else search_criteria.inject([]) do |res, criterion| res.concat target_universe.get_entities(criterion: :by_uniq_key, value: criterion.to_a) end end end def extra_params_to_entity_types(params = config.command_line_layer.extra_parameters) known_entity_types = project.engine.available_entity_types return known_entity_types if params.empty? params.map do |possible_entity_type| possible_entity_type = possible_entity_type.to_sym raise PowerStencil::Error, "Invalid entity type '#{possible_entity_type}' !" unless known_entity_types.include? possible_entity_type possible_entity_type end end def extra_params_to_entity_search_criteria(params) criteria = [] next_entity_reference = EntitySearchReference.new stack = params.dup if config[:regexp] criteria = stack else stack.each do |param| if md = param.match(/^\s*(?[^\/]+)\/(?.+)\s*$/) next_entity_reference.type = md[:type].to_sym next_entity_reference.name = md[:name] else if next_entity_reference.type.nil? or next_entity_reference.type.empty? next_entity_reference.type = param.to_sym else next_entity_reference.name = param end end next unless reference_complete? next_entity_reference logger.debug "Found entity search pattern in params: #{next_entity_reference.inspect}" criteria << next_entity_reference next_entity_reference = EntitySearchReference.new end unless next_entity_reference.type.nil? raise PowerStencil::Error, "Invalid parameter '#{next_entity_reference.type}' !" end end criteria end private def build_entity_type_report(entity_type, report = {}) klass = project.engine.available_entities_hash[entity_type] report[klass] ||= {fields: {}, methods: {}, special_methods: {}} entity_type_info = report[klass] # Fields klass.fields_constraints.each do |field_name, constraints| next if constraints[:reverse_method] entity_type_info[:fields][field_name] = {} constraints.each do |constraint_name, constraints_value| entity_type_info[:fields][field_name][constraint_name] = constraints_value end end # Methods klass.public_instance_methods(false).select do |method_name| klass.method_defined? method_name end .each do |method_name| entity_type_info[:methods][method_name] = klass end # Special methods klass.fields_constraints.each do |method_name, constraints| next unless constraints[:reverse_method] entity_type_info[:special_methods][method_name] = constraints[:reverse_method] end report end def analyse_extra_params(extra_params = config.command_line_layer.extra_parameters, default: ['']) params_to_check = if extra_params.empty? then config[:regexp] = true default else extra_params end extra_params_to_entity_search_criteria params_to_check end def reference_complete?(reference) return false if (reference.type.nil? or reference.name.nil?) return false if (reference.type.empty? or reference.name.empty?) true end end end end