%%-------------------------------------------------------------------- %% %% %CopyrightBegin% %% %% Copyright Ericsson AB 2001-2016. All Rights Reserved. %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. %% You may obtain a copy of the License at %% %% http://www.apache.org/licenses/LICENSE-2.0 %% %% Unless required by applicable law or agreed to in writing, software %% distributed under the License is distributed on an "AS IS" BASIS, %% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. %% See the License for the specific language governing permissions and %% limitations under the License. %% %% %CopyrightEnd% %% %% %%---------------------------------------------------------------------- %% File : cosEventApp.erl %% Description : %% %%---------------------------------------------------------------------- -module(cosEventApp). %%--------------- INCLUDES ----------------------------------- -include_lib("orber/include/corba.hrl"). -include("cosEventApp.hrl"). %%--------------- EXPORTS------------------------------------- %% cosEvent API external -export([start/0, stop/0, install/0, uninstall/0, start_channel/0, start_channel/1, start_channel_link/0, start_channel_link/1, stop_channel/1]). %% cosEvent API internal -export([create_link/3, get_option/2, type_check/3, disconnect/3, do_disconnect/3]). %% Application callbacks -export([start/2, init/1, stop/1]). %%--------------- DEFINES ------------------------------------ -define(IDL_MODULES, ['oe_CosEventComm', 'oe_CosEventChannelAdmin', 'oe_cosEventApp']). -define(SUPERVISOR_NAME, oe_cosEventSup). -define(SUP_FLAG, {simple_one_for_one,50,10}). -define(SUP_SPEC(Name, Args), ['CosEventChannel_EventChannel',Args, [{sup_child, true}, {regname, {global, Name}}]]). -define(SUP_CHILD, {"oe_EventChild", {cosEventApp,create_link, []}, transient,100000,worker, ['CosEventChannel_EventChannel']}). %%-----------------------------------------------------------% %% function : install %% Arguments: - %% Returns : ok | EXIT | EXCEPTION %% Effect : Install necessary data in the IFR DB %%------------------------------------------------------------ install() -> case install_loop(?IDL_MODULES, []) of ok -> ok; {error, Reason} -> exit(Reason) end. install_loop([], _) -> ok; install_loop([H|T], Accum) -> case catch H:'oe_register'() of {'EXIT',{unregistered,App}} -> ?write_ErrorMsg("Unable to register '~p'; application ~p not registered.\n" "Trying to unregister ~p~n", [H,App,Accum]), uninstall_loop(Accum, {exit, register}); {'EXCEPTION',_} -> ?write_ErrorMsg("Unable to register '~p'; propably already registered.\n" "You are adviced to confirm this.\n" "Trying to unregister ~p~n", [H,Accum]), uninstall_loop(Accum, {exit, register}); ok -> install_loop(T, [H|Accum]); _ -> ?write_ErrorMsg("Unable to register '~p'; reason unknown.\n" "Trying to unregister ~p~n", [H,Accum]), uninstall_loop(Accum, {exit, register}) end. %%-----------------------------------------------------------% %% function : uninstall %% Arguments: - %% Returns : ok | EXIT | EXCEPTION %% Effect : Remove data related to cosEvent from the IFR DB %%------------------------------------------------------------ uninstall() -> case uninstall_loop(lists:reverse(?IDL_MODULES), ok) of ok -> ok; {error, Reason} -> exit(Reason) end. uninstall_loop([],ok) -> ok; uninstall_loop([],{exit, register}) -> {error, {?MODULE, "oe_register failed"}}; uninstall_loop([],{exit, unregister}) -> {error, {?MODULE, "oe_unregister failed"}}; uninstall_loop([],{exit, both}) -> {error, {?MODULE, "oe_register and, for some of those already registered, oe_unregister failed"}}; uninstall_loop([H|T], Status) -> case catch H:'oe_unregister'() of ok -> uninstall_loop(T, Status); _ when Status == ok -> ?write_ErrorMsg("Unable to unregister '~p'; propably already unregistered.\n" "You are adviced to confirm this.\n",[H]), uninstall_loop(T, {exit, unregister}); _ -> ?write_ErrorMsg("Unable to unregister '~p'; propably already unregistered.\n" "You are adviced to confirm this.\n",[H]), uninstall_loop(T, {exit, both}) end. %%-----------------------------------------------------------% %% function : start/stop %% Arguments: %% Returns : %% Effect : Starts or stops the cosTime application. %%------------------------------------------------------------ start() -> application:start(cosEvent). stop() -> application:stop(cosEvent). %%-----------------------------------------------------------% %% function : start %% Arguments: Type - see module application %% Arg - see module application %% Returns : %% Effect : Module callback for application %%------------------------------------------------------------ start(_, _) -> supervisor:start_link({local, ?SUPERVISOR_NAME}, cosEventApp, app_init). %%-----------------------------------------------------------% %% function : stop %% Arguments: Arg - see module application %% Returns : %% Effect : Module callback for application %%------------------------------------------------------------ stop(_) -> ok. %%-----------------------------------------------------------% %% function : start_channel %% Arguments: - %% Returns : %% Effect : %%------------------------------------------------------------ start_channel() -> start_channel(?DEFAULT_OPTIONS). start_channel(Options) when is_list(Options) -> ServerOpts = get_option(?SERVER, Options), 'oe_CosEventComm_Channel':oe_create([Options, ServerOpts], ServerOpts); start_channel(Options) -> orber:dbg("[~p] cosEventApp:start_channel(~p);~n" "Options not correct.", [?LINE, Options], ?DEBUG_LEVEL), corba:raise(#'BAD_PARAM'{completion_status=?COMPLETED_NO}). %%-----------------------------------------------------------% %% function : start_channel %% Arguments: - %% Returns : %% Effect : %%------------------------------------------------------------ start_channel_link() -> start_channel_link(?DEFAULT_OPTIONS). start_channel_link(Options) when is_list(Options) -> ServerOpts = get_option(?SERVER, Options), 'oe_CosEventComm_Channel':oe_create_link([Options, ServerOpts], ServerOpts); start_channel_link(Options) -> orber:dbg("[~p] cosEventApp:start_channel_link(~p);~n" "Options not correct.", [?LINE, Options], ?DEBUG_LEVEL), corba:raise(#'BAD_PARAM'{completion_status=?COMPLETED_NO}). %%-----------------------------------------------------------% %% function : stop_factory %% Arguments: ChannelObj %% Returns : %% Effect : %%------------------------------------------------------------ stop_channel(ChannelObj) -> corba:dispose(ChannelObj). %%-----------------------------------------------------------% %% function : init %% Arguments: %% Returns : %% Effect : %%------------------------------------------------------------ %% Starting using create_factory/X init(own_init) -> {ok,{?SUP_FLAG, [?SUP_CHILD]}}; %% When starting as an application. init(app_init) -> {ok,{?SUP_FLAG, [?SUP_CHILD]}}. %%-----------------------------------------------------------% %% function : create_link %% Arguments: Module - which Module to call %% Env/ArgList - ordinary oe_create arguments. %% Returns : %% Exception: %% Effect : Necessary since we want the supervisor to be a %% 'simple_one_for_one'. Otherwise, using for example, %% 'one_for_one', we have to call supervisor:delete_child %% to remove the childs startspecification from the %% supervisors internal state. %%------------------------------------------------------------ create_link(Module, Env, ArgList) -> Module:oe_create_link(Env, ArgList). %%-----------------------------------------------------------% %% function : get_option %% Arguments: %% Returns : %% Exception: %% Effect : %%------------------------------------------------------------ get_option(Key, OptionList) -> case lists:keysearch(Key, 1, OptionList) of {value,{Key,Value}} -> Value; _ -> case lists:keysearch(Key, 1, ?DEFAULT_OPTIONS) of {value,{Key,Value}} -> Value; _-> {error, "Invalid option"} end end. %%-----------------------------------------------------------% %% function : type_check %% Arguments: Obj - objectrefernce to test. %% Mod - Module which contains typeID/0. %% Returns : 'ok' or raises exception. %% Effect : %%------------------------------------------------------------ type_check(_Obj, _Mod, false) -> ok; type_check(Obj, Mod, _) -> case catch corba_object:is_a(Obj, Mod:typeID()) of true -> ok; _ -> orber:dbg("[~p] cosEventApp:type_check(~p) failed; Should be ~p", [?LINE, Obj, Mod], ?DEBUG_LEVEL), corba:raise(#'BAD_PARAM'{completion_status=?COMPLETED_NO}) end. %%-----------------------------------------------------------% %% function : disconnect %% Arguments: Module - one of the interfaces defined in CosEventComm. %% Function - the appropriate disconnect function. %% Object - the client object reference. %% Returns : ok %% Exception: %% Effect : If the process would try to diconnect itself it could %% result in a deadlock. Hence, we spawn a new process to do it. %%------------------------------------------------------------ disconnect(Module, Function, Object) -> spawn(cosEventApp, do_disconnect, [Module, Function, Object]), ok. do_disconnect(Module, Function, Object) -> catch Module:Function(Object), ?DBG("Disconnect ~p:~p(..).~n", [Module, Function]), ok. %%--------------- END OF MODULE ------------------------------