class EL_PYXIS_OBJECT_EXPORTER
Exports object conforming to EL_REFLECTIVELY_SETTABLE as Pyxis document format
note
description: "Exports object conforming to ${EL_REFLECTIVELY_SETTABLE} as Pyxis document format"
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-11-06 10:49:11 GMT (Wednesday 6th November 2024)"
revision: "12"
class
EL_PYXIS_OBJECT_EXPORTER [G -> EL_REFLECTIVELY_SETTABLE create make_default end]
inherit
ANY
EL_REFLECTION_HANDLER
EL_MODULE_PYXIS; EL_MODULE_TUPLE
EL_SHARED_ZSTRING_BUFFER_POOL
create
make, make_default
feature {NONE} -- Initialization
make (a_object: G)
do
object := a_object
end
make_default
do
create {G} object.make_default
end
feature -- Element change
set_object (a_object: G)
do
object := a_object
end
feature -- Basic operations
put_header (output: EL_OUTPUT_MEDIUM; software_version: NATURAL)
do
output.put_line (
Pyxis_header #$ [output.encoding_name, Pyxis.root_element_name_for_type ({G}), software_version]
)
end
put_item (a_object: EL_REFLECTIVE; output: EL_OUTPUT_MEDIUM; tab_count: INTEGER)
do
object := a_object
output.put_indented_line (tab_count + 1, Item_element)
put (output, tab_count + 2)
end
put (output: EL_OUTPUT_MEDIUM; tab_count: INTEGER)
local
name: STRING; is_attribute: SPECIAL [BOOLEAN]
do
create is_attribute.make_filled (False, object.field_table.count)
put_attributes (output, tab_count, is_attribute)
across object.meta_data.alphabetical_list as list loop
name := list.item.name
if not is_attribute [list.cursor_index - 1] then
if attached {EL_REFLECTED_COLLECTION [ANY]} list.item as collection_field then
put_collection (output, tab_count, collection_field)
elseif attached {EL_REFLECTED_TUPLE} list.item as tuple_field
and then attached tuple_field.value (object) as l_tuple
and then attached tuple_field.field_name_list as name_list
then
put_field (output, name, tab_count)
put_tuple (output, tab_count + 1, tuple_field, l_tuple, name_list)
elseif attached {EL_REFLECTED_REFERENCE [ANY]} list.item as field
and then attached {EL_REFLECTIVE} field.value (object) as reflective
then
put_field (output, name, tab_count)
if attached object as previous then
object := reflective
put (output, tab_count + 1)
object := previous
end
elseif attached String_pool.borrowed_item as borrowed then
if attached borrowed.empty as value then
list.item.append_to_string (object, value)
if value.has ('%N') then
put_field (output, name, tab_count)
put_manifest (output, value, tab_count + 1)
elseif value.count > 0 then
value.enclose ('"', '"')
put_field (output, name, tab_count)
output.put_indented_line (tab_count + 1, value)
end
end
borrowed.return
end
end
end
end
feature {NONE} -- Implementation
put_attributes (output: EL_OUTPUT_MEDIUM; tab_count: INTEGER; is_attribute: SPECIAL [BOOLEAN])
local
value: ZSTRING; name: STRING; line_index, i: INTEGER
type: EL_ATTRIBUTE_TYPE_ROUTINES
do
if attached Once_attribute_lines as attribute_lines
and then attached object.meta_data.alphabetical_list as alphabetical_list
and then attached String_pool.borrowed_batch (alphabetical_list.count) as borrowed
then
across alphabetical_list as list loop
-- output numeric as Pyxis element attributes
name := list.item.name
line_index := type.attribute_id (object, list.item)
if line_index > 0 then
i := list.cursor_index - 1
is_attribute [i] := True
value := borrowed [i].empty
list.item.append_to_string (object, value)
if value.count > 0 then
attribute_lines.extend (line_index, name, value)
end
end
end
attribute_lines.put (output, tab_count)
String_pool.return (borrowed)
end
end
put_collection (output: EL_OUTPUT_MEDIUM; tab_count: INTEGER; collection_field: EL_REFLECTED_COLLECTION [ANY])
do
if attached {EL_REFLECTED_COLLECTION [EL_REFLECTIVE]} collection_field as reflective
and then attached reflective.collection (object) as collection
then
if not collection.is_empty then
put_field (output, collection_field.name, tab_count)
put_recursive_list (output, tab_count, collection.linear_representation)
end
elseif attached collection_field.to_string_list (object) as string_list then
if not string_list.is_empty then
put_field (output, collection_field.name, tab_count)
put_item_list (output, tab_count + 1, string_list)
end
end
end
put_field (output: EL_OUTPUT_MEDIUM; name: STRING; tab_count: INTEGER)
do
output.put_indent (tab_count)
output.put_string_8 (name)
output.put_character_8 (':')
output.put_new_line
end
put_item_list (output: EL_OUTPUT_MEDIUM; tab_count: INTEGER; list: LIST [READABLE_STRING_GENERAL])
do
output.put_indented_line (tab_count, Item_element)
from list.start until list.after loop
output.put_indent (tab_count + 1)
output.put_character_8 ('"')
output.put_string_general (list.item)
output.put_character_8 ('"')
output.put_new_line
list.forth
end
end
put_manifest (output: EL_OUTPUT_MEDIUM; str: ZSTRING; tab_count: INTEGER)
do
output.put_indented_line (tab_count, Pyxis_triple_quote)
across str.split ('%N') as line loop
output.put_indented_line (tab_count + 1, line.item)
end
output.put_indented_line (tab_count, Pyxis_triple_quote)
end
put_recursive_list (output: EL_OUTPUT_MEDIUM; tab_count: INTEGER; list: LINEAR [EL_REFLECTIVE])
do
if attached object as l_object then
from list.start until list.after loop
put_item (list.item, output, tab_count)
list.forth
end
object := l_object
end
end
put_tuple (
output: EL_OUTPUT_MEDIUM; tab_count: INTEGER; field: EL_REFLECTED_TUPLE; a_tuple: TUPLE
name_list: EL_STRING_8_LIST
)
local
value: ZSTRING; i: INTEGER
do
if attached Once_attribute_lines as attribute_lines then
if attached String_pool.borrowed_batch (a_tuple.count) as borrowed then
from i := 1 until i > a_tuple.count loop
value := borrowed [i - 1].empty
Tuple.write_i_th (a_tuple, i, value)
if field.member_types.i_th_is_character_data (i) then
attribute_lines.last.extend (value, name_list [i])
else
attribute_lines.first.extend (value, name_list [i])
end
i := i + 1
end
attribute_lines.put (output, tab_count)
String_pool.return (borrowed)
end
end
end
feature {NONE} -- Internal attributes
object: EL_REFLECTIVE
feature {NONE} -- Constants
Item_element: STRING = "item:"
Once_attribute_lines: EL_PYXIS_ATTRIBUTES
once
create Result.make
end
Pyxis_header: ZSTRING
once
Result := "[
pyxis-doc:
version = 1.0; encoding = "#"
#:
software_version = #
]"
end
Pyxis_triple_quote: ZSTRING
once
create Result.make_filled ('"', 3)
end
end