class EROS_REMOTELY_ACCESSIBLE
Client examples: FFT_COMPLEX_64 ; SIGNAL_MATH ; TYPE_TEST_SET
Object that is remotely accessible via EROS protocol
note
description: "Object that is remotely accessible via EROS protocol"
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: "2023-11-11 9:04:39 GMT (Saturday 11th November 2023)"
revision: "17"
deferred class
EROS_REMOTELY_ACCESSIBLE
inherit
EROS_OBJECT
rename
make_default as make
redefine
make
end
EL_MODULE_LOG; EL_MODULE_CONVERT_STRING
EROS_REMOTE_CALL_CONSTANTS
EROS_REMOTE_CALL_ERRORS
rename
make_default as make
redefine
make
end
feature {EROS_CALL_REQUEST_HANDLER_I} -- Initialization
make
--
do
Precursor {EROS_OBJECT}
Precursor {EROS_REMOTE_CALL_ERRORS}
create string_result.make
create argument_list.make_empty
routine := Default_routine
result_object := Procedure_acknowledgement
end
feature -- Access
result_object: EVOLICITY_SERIALIZEABLE_AS_XML
feature -- Element change
set_arguments (request_parser: EROS_CALL_REQUEST_PARSER)
-- set `routine' arguments
local
routine_name: STRING
do
log.enter (once "set_routine_with_arguments")
reset_errors
routine_name := request_parser.routine_name
argument_list := request_parser.argument_list
if routine_table.has_key (routine_name) then
routine := routine_table.found_item
if routine.arguments.count = argument_list.count then
if request_parser.has_call_argument then
set_request_arguments (request_parser.call_argument)
else
set_request_arguments (Void)
end
else
set_error (Error.wrong_number_of_arguments, "should be " + routine.arguments.count.out)
end
else
set_error (Error.routine_not_found, routine_name + "?")
routine := Default_routine
end
log.exit
end
feature -- Basic operations
call_routine
--
require
no_errors_setting_call_arguments: not has_error
do
log.enter (once "call_routine")
routine.apply
if routine.is_procedure then
result_object := Procedure_acknowledgement
elseif attached {FUNCTION [ANY]} routine.item as function then
if attached {EVOLICITY_SERIALIZEABLE_AS_XML} function.last_result as l_result then
result_object := l_result
elseif attached {STRING} function.last_result as last_result then
string_result.set_value (last_result)
result_object := string_result
else
string_result.set_value (function.last_result.out)
result_object := string_result
end
end
log.exit
end
feature -- Status query
is_routine_set: BOOLEAN
do
Result := routine /= Default_routine
end
function_requested: BOOLEAN
do
Result := routine.is_function
end
feature {NONE} -- Implementation
set_request_arguments (call_argument: detachable EL_BUILDABLE_FROM_NODE_SCAN)
local
argument: STRING; i: INTEGER; s: EL_STRING_8_ROUTINES
do
from i := 1 until i > argument_list.count or has_error loop
argument := argument_list [i]
if s.has_single_quotes (argument) then
s.remove_single_quote (argument)
set_string_argument (i, argument)
elseif s.has_enclosing (argument, '{', '}')
and then attached call_argument as deserialized_object
then
set_deserialized_object_argument (i, argument, deserialized_object)
elseif routine_table.has (argument) then
set_once_routine_argument (i, argument)
elseif Convert_string.is_convertible (argument, routine.argument_types [i]) then
-- Convertible to one of 13 basic types
routine.arguments.put (Convert_string.to_type (argument, routine.argument_types [i]), i)
else
set_type_mismatch_error (i, argument)
end
i := i + 1
end
end
set_string_argument (index: INTEGER; argument: STRING)
--
require
valid_argument: routine.arguments.valid_type_for_index (argument, index)
do
if routine.arguments.valid_type_for_index (argument, index) then
routine.arguments.put_reference (argument, index)
else
set_type_mismatch_error (index, argument)
end
end
set_deserialized_object_argument (index: INTEGER; argument: STRING; argument_object: EL_BUILDABLE_FROM_NODE_SCAN)
require
valid_argument_object: routine.arguments.valid_type_for_index (argument_object, index)
do
if routine.arguments.valid_type_for_index (argument_object, index) then
routine.arguments.put_reference (argument_object, index)
else
set_type_mismatch_error (index, argument)
end
end
set_once_routine_argument (index: INTEGER; routine_name: STRING)
--
require
once_function_exists: routine_table.has (routine_name)
once_function_takes_no_arguments: routine_table.item (routine_name).item.open_count = 0
valid_argument: valid_once_routine_argument (index, routine_name)
local
once_item: ANY
do
if routine_table.has_key (routine_name)
and then attached {FUNCTION [ANY]} routine_table.found_item.item as function
then
function.apply
once_item := function.last_result
if routine.arguments.valid_type_for_index (once_item, index) then
routine.arguments.put (once_item, index)
else
set_type_mismatch_error (index, routine_name)
end
else
set_error (Error.once_function_not_found, routine_name)
end
end
set_type_mismatch_error (index: INTEGER; argument: STRING)
do
set_error (
Error.argument_type_mismatch,
Type_mismatch_error_template #$ [argument, routine.argument_types.item (index).name]
)
end
valid_once_routine_argument (index: INTEGER; routine_name: STRING): BOOLEAN
do
if routine_table.has_key (routine_name)
and then attached {FUNCTION [ANY]} routine_table.found_item.item as function
then
function.apply
Result := routine.arguments.valid_type_for_index (function.last_result, index)
end
end
feature {NONE} -- Internal attributes
argument_list: EL_STRING_8_LIST
-- list of routine request arguments
string_result: EROS_STRING_RESULT
routine: EROS_ROUTINE
-- requested routine
feature {NONE} -- Constants
Default_routine: EROS_ROUTINE
once ("PROCESS")
create Result.make ("default", agent do_nothing)
end
Type_mismatch_error_template: ZSTRING
--
once
Result := "Cannot convert argument %"%S%" to type %S"
end
Procedure_acknowledgement: EROS_PROCEDURE_STATUS
--
once
create Result.make
end
end