class EL_REFLECTIVE_OBJECT_BUILDER_CONTEXT
EL_EIF_OBJ_BUILDER_CONTEXT for EL_REFLECTIVE object attribute
note
description: "${EL_EIF_OBJ_BUILDER_CONTEXT} for ${EL_REFLECTIVE} object attribute"
author: "Finnian Reilly"
copyright: "Copyright (c) 2001-2022 Finnian Reilly"
contact: "finnian at eiffel hyphen loop dot com"
license: "MIT license (See: en.wikipedia.org/wiki/MIT_License)"
date: "2024-09-23 8:06:39 GMT (Monday 23rd September 2024)"
revision: "11"
class
EL_REFLECTIVE_OBJECT_BUILDER_CONTEXT
inherit
EL_EIF_OBJ_BUILDER_CONTEXT
EL_REFLECTION_HANDLER
EL_MODULE_EIFFEL; EL_MODULE_TUPLE
EL_EIF_OBJ_BUILDER_CONTEXT_TYPE_CONSTANTS
EL_SHARED_CLASS_ID
create
make
feature {NONE} -- Initialization
make (a_object: EL_REFLECTIVE)
do
object := a_object
create context_table.make (3)
set_default_attributes
building_actions := new_building_actions
end
feature -- Element change
set_object (a_object: EL_REFLECTIVE)
do
object := a_object
end
feature {NONE} -- Build from XML
building_action_table: EL_PROCEDURE_TABLE [STRING]
-- Nodes relative to root element: bix
local
l_xpath: STRING; field: EL_REFLECTED_FIELD; s: EL_STRING_8_ROUTINES
type: EL_ATTRIBUTE_TYPE_ROUTINES; item_type_id: INTEGER
do
create Result.make (object.field_table.count)
across object.field_table as table loop
field := table.item
if type.attribute_id (object, field) > 0 then
l_xpath := s.character_string ('@') + field.name
if field.has_representation then
Result [l_xpath] := agent set_from_representation (field)
else
Result [l_xpath] := agent set_from_node (field)
end
elseif attached {EL_REFLECTED_TUPLE} field as tuple_field
and then attached tuple_field.field_name_list as name_list
then
across name_list as list loop
l_xpath := field.name + Attribute_path + list.item
item_type_id := tuple_field.member_types [list.cursor_index].type_id
Result [l_xpath] := agent set_tuple_item_from_node (tuple_field, list.cursor_index, item_type_id)
end
elseif attached {EL_REFLECTED_REFERENCE [ANY]} field as ref_field
and then attached new_build_action (ref_field, field.name) as action
then
Result [action.xpath] := action.procedure
else
Result [field.name + Text_path] := agent set_from_node (field)
end
end
end
extend_collection (field: EL_REFLECTED_COLLECTION [ANY])
do
field.extend_from_readable (object, node)
end
extend_reflective_collection (field: EL_REFLECTED_COLLECTION [EL_REFLECTIVE])
local
item_context: EL_REFLECTIVE_OBJECT_BUILDER_CONTEXT
do
field.extend_with_new (object)
if attached {CHAIN [EL_REFLECTIVE]} field.collection (object) as list then
if context_table.has_key (field.name) then
context_table.found_item.set_object (list.last)
else
create item_context.make (list.last)
context_table.put (item_context, field.name)
end
set_next_context (context_table.found_item)
end
end
set_from_node (field: EL_REFLECTED_FIELD)
require
not_has_representation: not field.has_representation
do
field.set_from_readable (object, node)
end
set_from_representation (field: EL_REFLECTED_FIELD)
do
field.set_from_string (object, node.adjusted (False))
end
set_reflective_field (field: EL_REFLECTED_REFERENCE [ANY])
local
context: EL_REFLECTIVE_OBJECT_BUILDER_CONTEXT
do
if attached {EL_REFLECTIVE} field.value (object) as value then
if context_table.has_key (field.name) then
context_table.found_item.set_object (value)
else
create context.make (value)
context_table.put (context, field.name)
end
set_next_context (context_table.found_item)
end
end
set_string_from_node (field: EL_REFLECTED_STRING [READABLE_STRING_GENERAL])
do
field.set_from_node (object, node)
end
set_tuple_item_from_node (field: EL_REFLECTED_TUPLE; index: INTEGER; type_id: INTEGER)
do
if attached field.value (object) as l_tuple then
Tuple.set_i_th (l_tuple, index, node, type_id)
end
end
feature {NONE} -- Implementation
new_build_action (field: EL_REFLECTED_REFERENCE [ANY]; name: STRING): TUPLE [xpath: STRING; procedure: PROCEDURE]
do
create Result
if attached {EL_REFLECTED_STRING [READABLE_STRING_GENERAL]} field as string_field then
Result := [name + Text_path, agent set_string_from_node (string_field)]
elseif attached {EL_REFLECTED_COLLECTION [ANY]} field as collection_field then
if attached {EL_REFLECTED_COLLECTION [EL_REFLECTIVE]} collection_field as reflective then
Result := [name + Item_path, agent extend_reflective_collection (reflective)]
else
Result := [name + Item_path + Text_path, agent extend_collection (collection_field)]
end
elseif attached {EL_REFLECTED_REFERENCE [ANY]} field as reflective
and then reflective.conforms_to_type (Class_id.EL_REFLECTIVE)
then
Result := [name, agent set_reflective_field (reflective)]
else
Result := [name + Text_path, agent set_from_node (field)]
end
end
feature {NONE} -- Internal attributes
context_table: EL_HASH_TABLE [EL_REFLECTIVE_OBJECT_BUILDER_CONTEXT, STRING]
object: EL_REFLECTIVE
end