767 lines
33 KiB
Lua
767 lines
33 KiB
Lua
--------------------------------------------------------------------------------
|
|
------------------------------ ##### ## ------------------------------
|
|
------------------------------ ## ## # ## ------------------------------
|
|
------------------------------ ## ## ## ## ------------------------------
|
|
------------------------------ ## ## # ## ------------------------------
|
|
------------------------------ ##### ### ###### ------------------------------
|
|
-------------------------------- --------------------------------
|
|
----------------------- An Object Request Broker in Lua ------------------------
|
|
--------------------------------------------------------------------------------
|
|
-- Project: OiL - ORB in Lua: An Object Request Broker in Lua --
|
|
-- Release: 0.4 alpha --
|
|
-- Title : OiL main programming interface (API) --
|
|
-- Authors: Renato Maia <maia@inf.puc-rio.br> --
|
|
--------------------------------------------------------------------------------
|
|
-- Interface: --
|
|
-- VERSION --
|
|
-- --
|
|
-- types --
|
|
-- loadidl(code) --
|
|
-- loadidlfile(path) --
|
|
-- getLIR() --
|
|
-- getIR() --
|
|
-- setIR(ir) --
|
|
-- --
|
|
-- newproxy(objref, [iface]) --
|
|
-- narrow(proxy, [iface]) --
|
|
-- --
|
|
-- newservant(impl, [iface], [key]) --
|
|
-- deactivate(object, [type]) --
|
|
-- tostring(object) --
|
|
-- --
|
|
-- pending() --
|
|
-- step() --
|
|
-- run() --
|
|
-- shutdown() --
|
|
-- --
|
|
-- newexcept(body) --
|
|
-- setexcatch(callback, [type]) --
|
|
-- --
|
|
-- newencoder() --
|
|
-- newdecoder(stream) --
|
|
-- --
|
|
-- setclientinterceptor([iceptor]) --
|
|
-- setserverinterceptor([iceptor]) --
|
|
-- --
|
|
-- init() --
|
|
-- main(function) --
|
|
-- newthread(function, ...) --
|
|
-- pcall(function, ...) --
|
|
-- sleep(time) --
|
|
-- time() --
|
|
-- tasks --
|
|
-- --
|
|
-- writeto(filepath, text) --
|
|
-- readfrom(filepath) --
|
|
--------------------------------------------------------------------------------
|
|
-- Notes: --
|
|
--------------------------------------------------------------------------------
|
|
|
|
local module = module
|
|
local luapcall = pcall
|
|
local require = require
|
|
|
|
local io = require "io"
|
|
local coroutine = require "coroutine"
|
|
|
|
local oo = require "oil.oo"
|
|
local builder = require "oil.builder"
|
|
local assert = require "oil.assert"
|
|
|
|
--------------------------------------------------------------------------------
|
|
-- OiL main programming interface (API).
|
|
|
|
-- This API provides access to the basic functionalities of the OiL ORB.
|
|
-- More advanced features may be accessed through more specialized interfaces
|
|
-- provided by internal components. OiL internal component organization is meant
|
|
-- to be customized for the application.
|
|
|
|
module "oil"
|
|
|
|
--------------------------------------------------------------------------------
|
|
-- Class that implements the OiL's broker API.
|
|
--
|
|
ORB = oo.class()
|
|
|
|
function ORB:__init(config)
|
|
self = oo.rawnew(self, builder.build(config.flavor, config))
|
|
|
|
------------------------------------------------------------------------------
|
|
-- Internal interface repository used by the ORB.
|
|
--
|
|
-- This is a alias for a facet of the Type Respository component of the
|
|
-- internal architecture.
|
|
-- If the current assembly does not provide this component, this field is
|
|
-- 'nil'.
|
|
--
|
|
-- @usage oil.types:register(oil.corba.idl.sequence{oil.corba.idl.string}) .
|
|
-- @usage oil.types:lookup("CORBA::StructDescription") .
|
|
-- @usage oil.types:lookup_id("IDL:omg.org/CORBA/InterfaceDef:1.0") .
|
|
--
|
|
if self.TypeRepository ~= nil then self.types = self.TypeRepository.types end
|
|
if self.ClientChannels ~= nil then self.ClientChannels.options = config.tcpoptions end
|
|
if self.ServerChannels ~= nil then self.ServerChannels.options = config.tcpoptions end
|
|
assert.results(self.ServerBroker.broker:initialize(self))
|
|
|
|
return self
|
|
end
|
|
|
|
--------------------------------------------------------------------------------
|
|
-- Loads an IDL code strip into the internal interface repository.
|
|
--
|
|
-- The IDL specified will be parsed by the LuaIDL compiler and the resulting
|
|
-- definitions are updated in the internal interface repository.
|
|
-- If any errors occurs during the parse no definitions are loaded into the IR.
|
|
--
|
|
-- @param idlspec string The IDL code strip to be loaded into the local IR.
|
|
-- @return ... object IDL descriptors that represents the loaded definitions.
|
|
--
|
|
-- @usage oil.loadidl [[
|
|
-- interface Hello {
|
|
-- attribute boolean quiet;
|
|
-- readonly attribute unsigned long count;
|
|
-- string say_hello_to(in string msg);
|
|
-- };
|
|
-- ]] .
|
|
--
|
|
function ORB:loadidl(idlspec)
|
|
assert.type(idlspec, "string", "IDL specification")
|
|
return assert.results(self.TypeRepository.compiler:load(idlspec))
|
|
end
|
|
|
|
--------------------------------------------------------------------------------
|
|
-- Loads an IDL file into the internal interface repository.
|
|
--
|
|
-- The file specified will be parsed by the LuaIDL compiler and the resulting
|
|
-- definitions are updated in the internal interface repository.
|
|
-- If any errors occurs during the parse no definitions are loaded into the IR.
|
|
--
|
|
-- @param filename string The path to the IDL file that must be loaded.
|
|
-- @return ... object IDL descriptors that represents the loaded definitions.
|
|
--
|
|
-- @usage oil.loadidlfile "/usr/local/corba/idl/CosNaming.idl" .
|
|
-- @usage oil.loadidlfile("HelloWorld.idl", "/tmp/preprocessed.idl") .
|
|
--
|
|
function ORB:loadidlfile(filepath)
|
|
assert.type(filepath, "string", "IDL file path")
|
|
return assert.results(self.TypeRepository.compiler:loadfile(filepath))
|
|
end
|
|
|
|
--------------------------------------------------------------------------------
|
|
-- Get the servant of the internal interface repository.
|
|
--
|
|
-- Function used to retrieve a reference to the integrated Interface Repository.
|
|
-- It returns a reference to the object that implements the internal Interface
|
|
-- Repository and exports local cached interface definitions.
|
|
--
|
|
-- @return proxy CORBA object that exports the local interface repository.
|
|
--
|
|
-- @usage oil.writeto("ir.ior", oil.tostring(oil.getLIR())) .
|
|
--
|
|
function ORB:getLIR()
|
|
return self:newservant(self.TypeRepository.types,
|
|
"InterfaceRepository",
|
|
"IDL:omg.org/CORBA/Repository:1.0")
|
|
end
|
|
|
|
--------------------------------------------------------------------------------
|
|
-- Get the remote interface repository used to retrieve interface definitions.
|
|
--
|
|
-- Function used to set the remote Interface Repository that must be used to
|
|
-- retrieve interface definitions not stored in the internal IR.
|
|
-- Once these definitions are acquired, they are stored in the internal IR.
|
|
--
|
|
-- @return proxy Proxy for the remote IR currently used.
|
|
--
|
|
function ORB:getIR()
|
|
return self.TypeRepository.delegated
|
|
end
|
|
|
|
--------------------------------------------------------------------------------
|
|
-- Defines a remote interface repository used to retrieve interface definitions.
|
|
--
|
|
-- Function used to get a reference to the Interface Repository used to retrieve
|
|
-- interface definitions not stored in the internal IR.
|
|
--
|
|
-- @param ir proxy Proxy for the remote IR to be used.
|
|
--
|
|
-- @usage oil.setIR(oil.newproxy("corbaloc::cos_host/InterfaceRepository",
|
|
-- "IDL:omg.org/CORBA/Repository:1.0")) .
|
|
--
|
|
function ORB:setIR(ir)
|
|
self.TypeRepository.delegated = ir
|
|
end
|
|
|
|
--------------------------------------------------------------------------------
|
|
-- Creates a proxy for a remote object defined by a textual reference.
|
|
--
|
|
-- The value of reference must be a string containing reference information of
|
|
-- the object the new new proxy will represent like a stringfied IOR
|
|
-- (Inter-operable Object Reference) or corbaloc.
|
|
-- Optionally, an interface supported by the remote object may be defined, in
|
|
-- this case no attempt is made to determine the actual object interface, i.e.
|
|
-- no network communication is made to check the object's interface.
|
|
--
|
|
-- @param object string Textual representation of object's reference the new
|
|
-- proxy will represent.
|
|
-- @param interface string [optional] Interface identification in the interface
|
|
-- repository, like a repID or absolute name of a interface the remote object
|
|
-- supports (no interface or type check is done).
|
|
--
|
|
-- @return table Proxy to the remote object.
|
|
--
|
|
-- @usage oil.newproxy("IOR:00000002B494...") .
|
|
-- @usage oil.newproxy("IOR:00000002B494...", "HelloWorld::Hello") .
|
|
-- @usage oil.newproxy("IOR:00000002B494...", "IDL:HelloWorld/Hello:1.0") .
|
|
-- @usage oil.newproxy("corbaloc::host:8080/Key", "IDL:HelloWorld/Hello:1.0") .
|
|
--
|
|
function ORB:newproxy(object, type)
|
|
assert.type(object, "string", "object reference")
|
|
return assert.results(self.ClientBroker.broker:fromstring(object, type))
|
|
end
|
|
|
|
--------------------------------------------------------------------------------
|
|
-- Narrow an object reference into some more specific interface supported by the
|
|
-- remote object.
|
|
--
|
|
-- The object's reference is defined as a proxy object.
|
|
-- If you wish to create a proxy to an object specified by a textual reference
|
|
-- like an IOR (Inter-operable Object Reference) that is already narrowed into
|
|
-- function.
|
|
-- The interface the object reference must be narrowed into is defined by the
|
|
-- parameter 'interface' (e.g. an interface repository ID).
|
|
-- If no interface is defined, then the object reference is narrowed to the most
|
|
-- specific interface supported by the remote object.
|
|
-- Note that in the former case, no attempt is made to determine the actual
|
|
-- object interface, i.e. no network communication is made to check the object's
|
|
-- interface.
|
|
--
|
|
-- @param proxy table Proxy that represents the remote object which reference
|
|
-- must be narrowed.
|
|
-- @param interface string [optional] Identification of the interface the
|
|
-- object reference must be narrowed into (no interface or type check is
|
|
-- made).
|
|
--
|
|
-- @return table New proxy to the remote object narrowed into some interface
|
|
-- supported by the object.
|
|
--
|
|
-- @usage oil.narrow(ns:resolve_str("HelloWorld")) .
|
|
-- @usage oil.narrow(ns:resolve_str("HelloWorld"), "IDL:HelloWorld/Hello:1.0") .
|
|
--
|
|
-- @see newproxy
|
|
--
|
|
function ORB:narrow(object, type)
|
|
assert.type(object, "table", "object proxy")
|
|
if type then assert.type(type, "string", "interface definition") end
|
|
if object and object._narrow then
|
|
return object:_narrow(type)
|
|
end
|
|
return object
|
|
end
|
|
|
|
--------------------------------------------------------------------------------
|
|
-- Creates a new servant implemented in Lua that supports some interface.
|
|
--
|
|
-- Function used to create a new servant from a table containing attribute
|
|
-- values and operation implementations.
|
|
-- The value of impl is used as the implementation of the a servant with
|
|
-- interface defined by parameter interface (e.g. repository ID or absolute
|
|
-- name of a given IDL interface stored in the IR).
|
|
-- Optionally, an object key value may be specified to create persistent
|
|
-- references.
|
|
-- The servant returned by this function offers all servant attributes and
|
|
-- methods, as well as implicit basic operations like CORBA's _interface or
|
|
-- _is_a.
|
|
-- After this call any requests which object key matches the key of the servant
|
|
-- are dispathed to its implementation.
|
|
--
|
|
-- @param object table Value used as the servant implementation (may be any
|
|
-- indexable value, e.g. userdata with a metatable that defined the __index
|
|
-- field).
|
|
-- @param interface string Interface identification line an absolute name of the
|
|
-- interface in the internal interface repository.
|
|
-- @param key string [optional] User-defined object key used in creation of the
|
|
-- object reference.
|
|
--
|
|
-- @return table servant created.
|
|
--
|
|
-- @usage oil.newservant({say_hello_to=print}, nil,"IDL:HelloWorld/Hello:1.0") .
|
|
-- @usage oil.newservant({say_hello_to=print}, nil,"::HelloWorld::Hello") .
|
|
-- @usage oil.newservant({say_hello_to=print}, "Key","::HelloWorld::Hello") .
|
|
--
|
|
function ORB:newservant(impl, key, type)
|
|
if not impl then assert.illegal(impl, "servant's implementation") end
|
|
if key then assert.type(key, "string", "servant's key") end
|
|
return assert.results(self.ServerBroker.broker:object(impl, key, type))
|
|
end
|
|
|
|
--------------------------------------------------------------------------------
|
|
-- Deactivates a servant by removing its implementation from the object map.
|
|
--
|
|
-- If 'object' is a servant (i.e. the object returned by 'newservant') then it
|
|
-- is deactivated.
|
|
-- Alternatively, the 'object' parameter may be the servant's object key.
|
|
-- Only in the case that the servant was created with an implicitly created key
|
|
-- by the ORB then the 'object' can be the servant's implementation.
|
|
-- Since a single implementation object can be used to create many servants with
|
|
-- different interface, in this case the 'type' parameter must be provided with
|
|
-- the exact servant's interface.
|
|
--
|
|
-- @param object string|object Servant's object key, servant's implementation or
|
|
-- servant itself.
|
|
-- @param type string Identification of the servant's interface (e.g. repository
|
|
-- ID or absolute name).
|
|
--
|
|
-- @usage oil.deactivate(oil.newservant(impl, "::MyInterface", "objkey")) .
|
|
-- @usage oil.deactivate("objkey") .
|
|
-- @usage oil.deactivate(impl, "MyInterface") .
|
|
--
|
|
function ORB:deactivate(object, type)
|
|
if not object then
|
|
assert.illegal(object,
|
|
"object reference (servant, implementation or object key expected)")
|
|
end
|
|
return self.ServerBroker.broker:remove(object, type)
|
|
end
|
|
|
|
--------------------------------------------------------------------------------
|
|
-- Returns textual information that identifies the servant.
|
|
--
|
|
-- This function is used to get textual information that references a servant
|
|
-- or proxy like an IOR (Inter-operable Object Reference).
|
|
--
|
|
-- @param servant object Servant which textual referecence must be taken.
|
|
--
|
|
-- @return string Textual referecence to the servant.
|
|
--
|
|
-- @usage oil.writeto("ref.ior", oil.tostring(oil.newservant(impl, "::Hello"))).
|
|
--
|
|
function ORB:tostring(object)
|
|
assert.type(object, "table", "servant object")
|
|
return assert.results(self.ServerBroker.broker:tostring(object))
|
|
end
|
|
|
|
--------------------------------------------------------------------------------
|
|
-- Checks whether there is some request pending
|
|
--
|
|
-- Function used to checks whether there is some unprocessed ORB request
|
|
-- pending.
|
|
-- It returns true if there is some request pending that must be processed by
|
|
-- the main ORB or false otherwise.
|
|
--
|
|
-- @return boolean True if there is some ORB request pending or false otherwise.
|
|
--
|
|
-- @usage while oil.pending() do oil.step() end .
|
|
--
|
|
function ORB:pending()
|
|
return assert.results(self.ServerBroker.broker:pending())
|
|
end
|
|
|
|
--------------------------------------------------------------------------------
|
|
-- Waits for an ORB request and process it.
|
|
--
|
|
-- Function used to wait for an ORB request and process it.
|
|
-- Only one single ORB request is processed at each call.
|
|
-- It returns true if no exception is raised during request processing, or 'nil'
|
|
-- and the raised exception otherwise.
|
|
--
|
|
-- @usage while oil.pending() do oil.step() end .
|
|
--
|
|
function ORB:step()
|
|
return assert.results(self.ServerBroker.broker:step())
|
|
end
|
|
|
|
--------------------------------------------------------------------------------
|
|
-- Runs the ORB main loop.
|
|
--
|
|
-- Function used to process all remote requisitions continuously until some
|
|
-- exception is raised.
|
|
-- If an exception is raised during the processing of requests this function
|
|
-- returns nil and the raised exception.
|
|
-- This function implicitly initiates the ORB if it was not initialized yet.
|
|
--
|
|
-- @see init
|
|
--
|
|
function ORB:run()
|
|
return assert.results(self.ServerBroker.broker:run())
|
|
end
|
|
|
|
--------------------------------------------------------------------------------
|
|
-- Shuts down the ORB.
|
|
--
|
|
-- Stops the ORB main loop if it is executing, handles all pending requests and
|
|
-- closes all connections.
|
|
--
|
|
-- @usage oil.shutdown()
|
|
--
|
|
function ORB:shutdown()
|
|
return assert.results(self.ServerBroker.broker:shutdown())
|
|
end
|
|
|
|
--------------------------------------------------------------------------------
|
|
-- Creates a new value encoder that marshal values into strings.
|
|
--
|
|
-- The encoder marshals values in a CORBA's CDR encapsulated stream, i.e.
|
|
-- includes an indication of the endianess used in value codification.
|
|
--
|
|
-- @return object Value encoder that provides operation 'put(value, [type])' to
|
|
-- marshal values and operation 'getdata()' to get the marshaled stream.
|
|
--
|
|
-- @usage encoder = oil.newencoder(); encoder:put({1,2,3}, oil.corba.idl.sequence{oil.corba.idl.long})
|
|
-- @usage encoder = oil.newencoder(); encoder:put({1,2,3}, oil.types:lookup("MyLongSeq"))
|
|
--
|
|
function ORB:newencoder()
|
|
return assert.results(self.ValueEncoder.codec:encoder(true))
|
|
end
|
|
|
|
--------------------------------------------------------------------------------
|
|
-- Creates a new value decoder that extracts marshaled values from strings.
|
|
--
|
|
-- The decoder reads CORBA's CDR encapsulated streams, i.e. includes an
|
|
-- indication of the endianess used in value codification.
|
|
--
|
|
-- @param stream string String containing a stream with marshaled values.
|
|
--
|
|
-- @return object Value decoder that provides operation 'get([type])' to
|
|
-- unmarshal values from a marshaled stream.
|
|
--
|
|
-- @usage decoder = oil.newdecoder(stream); val = decoder:get(oil.corba.idl.sequence{oil.corba.idl.long})
|
|
-- @usage decoder = oil.newdecoder(stream); val = decoder:get(oil.types:lookup("MyLongSeq"))
|
|
--
|
|
function ORB:newdecoder(stream)
|
|
assert.type(stream, "string", "byte stream")
|
|
return assert.results(self.ValueEncoder.codec:decoder(stream, true))
|
|
end
|
|
|
|
--------------------------------------------------------------------------------
|
|
-- Creates a new exception object with the given body.
|
|
--
|
|
-- The 'body' must contain the values of the exceptions fields and must also
|
|
-- contain the exception identification in index 1 (in CORBA this
|
|
-- identification is a repID).
|
|
--
|
|
-- @param body table Exception body with all its field values and exception ID.
|
|
--
|
|
-- @return object Exception that provides meta-method '__tostring' that provides
|
|
-- a pretty-printing.
|
|
--
|
|
-- @usage error(oil.newexcept{ "IDL:omg.org.CORBA/INTERNAL:1.0", minor_code_value = 2 })
|
|
--
|
|
function ORB:newexcept(body)
|
|
assert.type(body, "table", "exception body")
|
|
local except = assert.results(self.TypeRepository.types:resolve(body[1]))
|
|
assert.type(except, "idl except", "referenced exception type")
|
|
body[1] = except.repID
|
|
return assert.Exception(body)
|
|
end
|
|
|
|
--------------------------------------------------------------------------------
|
|
-- Defines a exception handling function for proxies.
|
|
--
|
|
-- The handling function receives the following parameters:
|
|
-- proxy : object proxy that perfomed the operation.
|
|
-- exception: exception/error raised.
|
|
-- operation: descriptor of the operation that raised the exception.
|
|
-- If the parameter 'type' is provided, then the exception handling function
|
|
-- will be applied only to proxies of that type (i.e. interface).
|
|
-- Exception handling functions are nor cumulative.
|
|
-- For example, is the is an exception handling function defined for all proxies
|
|
-- and other only for proxies of a given type, then the later will be used for
|
|
-- proxies of that given type.
|
|
-- Additionally, exceptions handlers are not inherited through interface
|
|
-- hierarchies.
|
|
--
|
|
-- @param handler function Exception handling function.
|
|
-- @param type string Interface ID of a group of proxies (e.g. repID).
|
|
--
|
|
-- @usage oil.setexcatch(function(_, except) error(tostring(except)) end)
|
|
--
|
|
function ORB:setexcatch(handler, type)
|
|
assert.results(self.ClientBroker.broker:excepthandler(handler, type))
|
|
end
|
|
|
|
--------------------------------------------------------------------------------
|
|
-- Sets a CORBA-specific interceptor for operation invocations in the client-size.
|
|
--
|
|
-- The interceptor must provide the following operations
|
|
--
|
|
-- send_request(request): 'request' structure is described below.
|
|
-- response_expected: [boolean] (read-only)
|
|
-- object_key: [string] (read-only)
|
|
-- operation: [string] (read-only) Operation name.
|
|
-- service_context: [table] Set this value to define a service context
|
|
-- values. See 'ServiceContextList' in CORBA specs.
|
|
-- success: [boolean] set this value to cancel invocation:
|
|
-- true ==> invocation successfull
|
|
-- false ==> invocation raised an exception
|
|
-- Note: The integer indexes store the operation's parameter values and
|
|
-- should also be used to store the results values if the request is canceled
|
|
-- (see note below).
|
|
--
|
|
-- receive_reply(reply): 'reply' structure is described below.
|
|
-- service_context: [table] (read-only) See 'ServiceContextList' in CORBA
|
|
-- specs.
|
|
-- reply_status: [string] (read-only)
|
|
-- success: [boolean] Identifies the kind of result:
|
|
-- true ==> invocation successfull
|
|
-- false ==> invocation raised an exception
|
|
-- Note: The integer indexes store the results that will be sent as request
|
|
-- result. For successful invocations these values must be the operation's
|
|
-- results (return, out and inout parameters) in the same order they appear
|
|
-- in the IDL description. For failed invocations, index 1 must be the
|
|
-- exception that identifies the failure.
|
|
--
|
|
-- The 'request' and 'reply' are the same table in a single invocation.
|
|
-- Therefore, the fields of 'request' are also available in 'reply' except for
|
|
-- those defined in the description of 'reply'.
|
|
--
|
|
function ORB:setclientinterceptor(iceptor)
|
|
if iceptor then
|
|
local ClientSide = require "oil.corba.interceptors.ClientSide"
|
|
iceptor = ClientSide{ interceptor = iceptor }
|
|
end
|
|
local port = require "loop.component.intercepted"
|
|
port.intercept(self.OperationRequester, "requests", "method", iceptor)
|
|
port.intercept(self.OperationRequester, "messenger", "method", iceptor)
|
|
end
|
|
|
|
--------------------------------------------------------------------------------
|
|
-- Sets a CORBA-specific interceptor for operation invocations in the server-size.
|
|
--
|
|
-- The interceptor must provide the following operations
|
|
--
|
|
-- receive_request(request): 'request' structure is described below.
|
|
-- service_context: [table] (read-only) See 'ServiceContextList' in CORBA
|
|
-- specs.
|
|
-- request_id: [number] (read-only)
|
|
-- response_expected: [boolean] (read-only)
|
|
-- object_key: [string] (read-only)
|
|
-- operation: [string] (read-only) Operation name.
|
|
-- servant: [object] (read-only) Local object the invocation will be dispatched to.
|
|
-- method: [function] (read-only) Function that will be invoked on object 'servant'.
|
|
-- success: [boolean] Set this value to cancel invocation:
|
|
-- true ==> invocation successfull
|
|
-- false ==> invocation raised an exception
|
|
-- Note: The integer indexes store the operation's parameter values and
|
|
-- should also be used to store the results values if the request is canceled
|
|
-- (see note below).
|
|
--
|
|
-- send_reply(reply): 'reply' structure is described below.
|
|
-- service_context: [table] Set this value to define a service context
|
|
-- values. See 'ServiceContextList' in CORBA specs.
|
|
-- success: [boolean] identifies the kind of result:
|
|
-- true ==> invocation successfull
|
|
-- false ==> invocation raised an exception
|
|
-- Note: The integer indexes store the results that will be sent as request
|
|
-- result. For successful invocations these values must be the operation's
|
|
-- results (return, out and inout parameters) in the same order they appear
|
|
-- in the IDL description. For failed invocations, index 1 must be the
|
|
-- exception that identifies the failure.
|
|
--
|
|
-- The 'request' and 'reply' are the same table in a single invocation.
|
|
-- Therefore, the fields of 'request' are also available in 'reply' except for
|
|
-- those defined in the description of 'reply'.
|
|
--
|
|
function ORB:setserverinterceptor(iceptor)
|
|
if iceptor then
|
|
local ServerSide = require "oil.corba.interceptors.ServerSide"
|
|
iceptor = ServerSide{ interceptor = iceptor }
|
|
end
|
|
local port = require "loop.component.intercepted"
|
|
port.intercept(self.RequestListener, "messenger", "method", iceptor)
|
|
port.intercept(self.RequestDispatcher, "dispatcher", "method", iceptor)
|
|
end
|
|
|
|
--------------------------------------------------------------------------------
|
|
--------------------------------------------------------------------------------
|
|
--------------------------------------------------------------------------------
|
|
|
|
VERSION = "OiL 0.4 beta"
|
|
|
|
if BasicSystem == nil then
|
|
local factories = require "oil.builder.cooperative"
|
|
BasicSystem = factories.BasicSystem()
|
|
end
|
|
|
|
--------------------------------------------------------------------------------
|
|
-- Initialize the OiL main ORB.
|
|
--
|
|
-- Creates and initialize a ORB instance with the provided configurations.
|
|
-- If no configuration is provided, a default ORB instance is returned.
|
|
-- The configuration values may differ accordingly to the underlying protocol.
|
|
-- For example, for CORBA brokers the current options are the host name or IP
|
|
-- address and port that ORB must bind to, as well as the host name or IP
|
|
-- address and port that must be used in creation of object references.
|
|
--
|
|
-- The 'flavor' configuration field defines a list of archtectural levels.
|
|
-- Each level defines a set of components and connections that extends the
|
|
-- following level.
|
|
--
|
|
-- Components are created by builder modules registered under namespace
|
|
-- 'oil.builder.*' that must provide a 'create(components)' function.
|
|
-- The parameter 'components' is a table with all components created by the
|
|
-- previous levels builders and that must be used to store the components
|
|
-- created by the builder.
|
|
--
|
|
-- Components created by a previous builder should not be replaced by components
|
|
-- created by following builders.
|
|
-- After all level components are they are assembled by assembler modules
|
|
-- registered under namespace 'oil.arch.*' that must provide a
|
|
-- 'assemble(components)' function.
|
|
-- The parameter 'components' is a table with all components created by the
|
|
-- levels builders.
|
|
--
|
|
-- @param config table Configuration used to create the ORB instance.
|
|
-- @return table The ORB instance created/obtained.
|
|
--
|
|
-- @usage oil.init() .
|
|
-- @usage oil.init{ host = "middleware.inf.puc-rio.br" } .
|
|
-- @usage oil.init{ host = "10.223.10.56", port = 8080 } .
|
|
-- @usage oil.init{ port = 8080, flavor = "corba;typed;base" } .
|
|
-- @usage oil.init{ port = 8080, flavor = "ludo;cooperative;base" } .
|
|
--
|
|
local DefaultORB
|
|
function init(config)
|
|
if config == nil then
|
|
if DefaultORB then return DefaultORB end
|
|
DefaultORB = {}
|
|
config = DefaultORB
|
|
end
|
|
if config.flavor == nil then
|
|
config.flavor = "corba;typed;cooperative;base"
|
|
end
|
|
if BasicSystem and config.BasicSystem == nil then
|
|
config.BasicSystem = BasicSystem
|
|
end
|
|
assert.type(config.flavor, "string", "ORB flavor")
|
|
return ORB(config)
|
|
end
|
|
|
|
--------------------------------------------------------------------------------
|
|
-- Internal coroutine scheduler used by OiL.
|
|
--
|
|
-- This is a alias for a facet of the Task Manager component of the internal
|
|
-- architecture.
|
|
-- If the current assembly does not provide this component, this field is 'nil'.
|
|
-- It provides the same API of the 'loop.thread.Scheduler' class.
|
|
--
|
|
-- @usage thread = oil.tasks:current()
|
|
-- @usage oil.tasks:suspend()
|
|
-- @usage oil.tasks:resume(thread)
|
|
--
|
|
tasks = BasicSystem and BasicSystem.tasks
|
|
|
|
--------------------------------------------------------------------------------
|
|
-- Function that must be used to perform protected calls in applications.
|
|
--
|
|
-- It is a 'coroutine-safe' version of the 'pcall' function of the Lua standard
|
|
-- library.
|
|
--
|
|
-- @param func function Function to be executed in protected mode.
|
|
-- @param ... any Additional parameters passed to protected function.
|
|
--
|
|
-- @param success boolean 'true' if function execution did not raised any errors
|
|
-- or 'false' otherwise.
|
|
-- @param ... any Values returned by the function or an the error raised by the
|
|
-- function.
|
|
--
|
|
pcall = tasks and tasks:getpcall() or luapcall
|
|
|
|
--------------------------------------------------------------------------------
|
|
-- Function executes the main function of the application.
|
|
--
|
|
-- The application's main function is executed in a new thread if the current
|
|
-- assembly provides thread support.
|
|
-- This may only return when the application terminates.
|
|
--
|
|
-- @param main function Appplication's main function.
|
|
--
|
|
-- @usage oil.main(oil.run)
|
|
-- @usage oil.main(function() print(oil.tostring(oil.getLIR())) oil.run() end)
|
|
--
|
|
function main(main, ...)
|
|
assert.type(main, "function", "main function")
|
|
if tasks then
|
|
assert.results(tasks:register(coroutine.create(main), tasks.currentkey))
|
|
return BasicSystem.control:run(...)
|
|
else
|
|
return main(...)
|
|
end
|
|
end
|
|
|
|
--------------------------------------------------------------------------------
|
|
-- Creates and starts the execution of a new the thread.
|
|
--
|
|
-- Creates a new thread to execute the function 'func' with the extra parameters
|
|
-- provided.
|
|
-- This function imediately starts the execution of the new thread and the
|
|
-- original thread is only resumed again acordingly to the the scheduler's
|
|
-- internal policy.
|
|
-- This function can only be invocated from others threads, including the one
|
|
-- executing the application's main function (see 'main').
|
|
--
|
|
-- @param func function Function that the new thread will execute.
|
|
-- @param ... any Additional parameters passed to the 'func' function.
|
|
--
|
|
-- @usage oil.main(function() oil.newthread(oil.run) oil.newproxy(oil.readfrom("ior")):register(localobj) end)
|
|
--
|
|
-- @see main
|
|
--
|
|
function newthread(func, ...)
|
|
assert.type(func, "function", "thread body")
|
|
return tasks:start(func, ...)
|
|
end
|
|
|
|
--------------------------------------------------------------------------------
|
|
-- Suspends the execution of the current thread for some time.
|
|
--
|
|
-- @param time number Delay in seconds that the execution must be resumed.
|
|
--
|
|
-- @usage oil.sleep(5.5)
|
|
--
|
|
function sleep(time)
|
|
assert.type(time, "number", "time")
|
|
return BasicSystem.sockets:sleep(time)
|
|
end
|
|
|
|
--------------------------------------------------------------------------------
|
|
-- Get the current system time.
|
|
--
|
|
-- @return number Number of seconds since a fixed point in the past.
|
|
--
|
|
-- @usage local start = oil.time(); oil.sleep(3); print("I slept for", oil.time() - start)
|
|
--
|
|
function time()
|
|
return BasicSystem.sockets:gettime()
|
|
end
|
|
|
|
--------------------------------------------------------------------------------
|
|
-- Writes a text into file.
|
|
--
|
|
-- Utility function for writing stringfied IORs into a file.
|
|
--
|
|
function writeto(filepath, text)
|
|
local result, errmsg = io.open(filepath, "w")
|
|
if result then
|
|
local file = result
|
|
result, errmsg = file:write(text)
|
|
file:close()
|
|
end
|
|
return result, errmsg
|
|
end
|
|
|
|
--------------------------------------------------------------------------------
|
|
-- Read the contents of a file.
|
|
--
|
|
-- Utility function for reading stringfied IORs from a file.
|
|
--
|
|
function readfrom(filepath)
|
|
local result, errmsg = io.open(filepath)
|
|
if result then
|
|
local file = result
|
|
result, errmsg = file:read("*a")
|
|
file:close()
|
|
end
|
|
return result, errmsg
|
|
end
|