diff options
Diffstat (limited to 'lib/cosNotification/src/CosNotifyFilter_Filter_impl.erl')
-rw-r--r-- | lib/cosNotification/src/CosNotifyFilter_Filter_impl.erl | 670 |
1 files changed, 670 insertions, 0 deletions
diff --git a/lib/cosNotification/src/CosNotifyFilter_Filter_impl.erl b/lib/cosNotification/src/CosNotifyFilter_Filter_impl.erl new file mode 100644 index 0000000000..042e180170 --- /dev/null +++ b/lib/cosNotification/src/CosNotifyFilter_Filter_impl.erl @@ -0,0 +1,670 @@ +%%-------------------------------------------------------------------- +%% +%% %CopyrightBegin% +%% +%% Copyright Ericsson AB 1999-2009. All Rights Reserved. +%% +%% The contents of this file are subject to the Erlang Public License, +%% Version 1.1, (the "License"); you may not use this file except in +%% compliance with the License. You should have received a copy of the +%% Erlang Public License along with this software. If not, it can be +%% retrieved online at http://www.erlang.org/. +%% +%% Software distributed under the License is distributed on an "AS IS" +%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See +%% the License for the specific language governing rights and limitations +%% under the License. +%% +%% %CopyrightEnd% +%% +%% +%%---------------------------------------------------------------------- +%% File : CosNotifyFilter_Filter_impl.erl +%% Purpose : +%% Note : For an event to be forwarded it's sufficient that at least +%% one of the constraints return 'true'. +%% ALL functions in this module are internal. May NOT be used +%% externally in ANY WAY; only CosNotification system modules. +%%---------------------------------------------------------------------- + +-module('CosNotifyFilter_Filter_impl'). + +%%--------------- INCLUDES ----------------------------------- +%% Application files +-include_lib("orber/include/corba.hrl"). +-include_lib("orber/include/ifr_types.hrl"). +%% Application files +-include("CosNotification.hrl"). +-include("CosNotifyChannelAdmin.hrl"). +-include("CosNotifyComm.hrl"). +-include("CosNotifyFilter.hrl"). +-include("CosNotification_Definitions.hrl"). + +%%--------------- IMPORTS ------------------------------------ + +%%--------------- EXPORTS ------------------------------------ +%% External Attributes +-export(['_get_constraint_grammar'/2]). +%% External Functions +-export([add_constraints/3, + modify_constraints/4, + get_constraints/3, + get_all_constraints/2, + remove_all_constraints/2, + destroy/2, + match/3, + match_structured/3, + match_typed/3, + attach_callback/3, + detach_callback/3, + get_callbacks/2]). + +%%--------------- gen_server specific exports ---------------- +-export([handle_info/2, code_change/3]). +-export([init/1, terminate/2]). + +%%--------------- LOCAL DEFINITIONS -------------------------- +%%######### MISC ########## +-define(create_ConstraintInfo(_Types, _Con, _ID), + #'CosNotifyFilter_ConstraintInfo'{ + constraint_expression = + #'CosNotifyFilter_ConstraintExp'{ + event_types = _Types, + constraint_expr = _Con}, + constraint_id = _ID + }). + +%%#### Data structures #### +-record(state, {constraint_grammar, + constraints = [], + filters = [], + callbacks = [], + idCounter = 0, + filterFactory, + factoryPid, + etsR}). + +%% Data structures constructors +-define(get_InitState(Fac, Pid, Gr), + #state{constraint_grammar=Gr, + filterFactory=Fac, + factoryPid=Pid, + etsR = ets:new(oe_ets, [bag, protected])}). + +%%------------------- Data structures selectors ------------------- +%% Grammar +-define(get_Grammar(S), S#state.constraint_grammar). +%% Callbacks +% Left out for now to avoid dialyzer warning. +%-define(get_Callback(S,I), find_obj(lists:keysearch(I, 1, S#state.callbacks), +% callback)). +-define(get_AllCallback(S), lists:map(fun({_V, C}) -> C end, + S#state.callbacks)). +-define(get_AllCallbackID(S), lists:map(fun({V, _C}) -> V end, + S#state.callbacks)). +%% ID:s +-define(get_IdCounter(S), S#state.idCounter). + +%% Constraints +-define(get_Constraint(S,I), find_obj(lists:keysearch(I, 1, S#state.constraints), + constraint)). +-define(get_AllConstraints(S), lists:map(fun({I, C, _W, _WC, _K, T}) -> + ?create_ConstraintInfo(T, C, I) + end, + S#state.constraints)). +-define(get_ConstraintAllData(S), S#state.constraints). +-define(get_ConstraintData(S,I), lists:keysearch(I, 1, S#state.constraints)). +-define(match_Type(S,I,ET), ets:lookup(S#state.etsR, {I, ET})). +%% Parse Tree +-define(get_ParseTree(S,K), find_obj(ets:lookup(S#state.etsR, K), tree)). + +%%------------------- Data structures modifiers ------------------- +%% Callbacks +-define(del_Callback(S,I), S#state{callbacks = + delete_obj(lists:keydelete(I,1, + S#state.callbacks), + S#state.callbacks, callback)}). +-define(del_AllCallbacks(S), S#state{callbacks=[]}). +-define(add_Callback(S,V,C), S#state{idCounter=V, + callbacks = [{V,C}|S#state.callbacks]}). +%% ID:s +-define(set_IdCounter(S,V), S#state{idCounter=V}). +-define(new_Id(S), 'CosNotification_Common':create_id(S#state.idCounter)). + +%% Constraints +-define(del_Constraint(S, I), match_delete(S, S#state.constraints, I)). +-define(del_AllConstraints(S), clear_DB(S)). +-define(add_Constraint(S,I,C,W,_WC,K,T), S#state{constraints = + [{I, C, W, _WC, K, T}|S#state.constraints]}). +-define(set_Constraints(S,C), S#state{constraints = C}). + +-define(del_AllTypes(S), ets:match_delete(S#state.etsR, {'_','_',types})). +-define(del_Type(S,I), ets:match_delete(S#state.etsR, {{I, '_'}, '_', types})). +-define(add_Type(S,I,ET,K), ets:insert(S#state.etsR, {{I, ET}, K, types})). + +%% Parse Tree +-define(add_ParseTree(S,K,T), ets:insert(S#state.etsR, {K, T, tree})). +-define(del_ParseTree(S,K), ets:delete(S#state.etsR, K)). +-define(del_AllParseTress(S), ets:match_delete(S#state.etsR, {'_','_',tree})). + +%%------------------- MISC ---------------------------------------- +-define(is_EmptyFilter(S), S#state.constraints==[]). + +-define(InfoSeq2EventTypeSeq(L), lists:flatten( + lists:map(fun(#'CosNotifyFilter_ConstraintInfo' + {constraint_expression= + #'CosNotifyFilter_ConstraintExp' + {event_types = ET}}) -> + ET + end, + L))). + +%%-----------------------------------------------------------% +%% Function : handle_info, code_change +%% Arguments: See gen_server documentation. +%% Effect : Functions demanded by the gen_server module. +%%------------------------------------------------------------ + +code_change(_OldVsn, State, _Extra) -> + {ok, State}. + +handle_info(Info, State) -> + ?debug_print("INFO: ~p DATA: ~p~n", [State, Info]), + case Info of + {'EXIT', _Pid, _Reason} -> + {noreply, State}; + _ -> + {noreply, State} + end. + +%%----------------------------------------------------------% +%% Function : init, terminate +%% Arguments: +%%----------------------------------------------------------- + +init([FiFac, FacPid, ConstraintGr]) -> + process_flag(trap_exit, true), + {ok, ?get_InitState(FiFac, FacPid, ConstraintGr)}. + +terminate(_Reason, _State) -> + ok. + +%%----------------------------------------------------------- +%%------- Exported external attributes ---------------------- +%%----------------------------------------------------------- +%%----------------------------------------------------------% +%% Function : '_get_constraint_grammar'/2 +%% Type : readonly +%% Returns : Grammar - string() +%%----------------------------------------------------------- +'_get_constraint_grammar'(_OE_THIS, State) -> + {reply, ?get_Grammar(State), State}. + +%%----------------------------------------------------------- +%%------- Exported external functions ----------------------- +%%----------------------------------------------------------- +%%----------------------------------------------------------% +%% Function : add_constraints/3 +%% Arguments: CL - CosNotifyFilter::ConstraintExpSeq +%% Returns : CosNotifyFilter::ConstraintInfoSeq | +%% {'EXCEPTION', CosNotifyFilter::InvalidConstraint} +%%----------------------------------------------------------- +add_constraints(_OE_THIS, State, CL) -> + {NewState, Filters, Info, EventTSeq} = try_create_filters(State, CL), + NewState2=store_filters(NewState, Filters), + inform_callbacks(?get_AllCallback(NewState2), EventTSeq, []), + {reply, Info, NewState2}. + +%%----------------------------------------------------------% +%% Function : modify_constraints/4 +%% Arguments: IDs - CosNotifyFilter::ConstraintIDSeq +%% AddConstraintInfoSeq - CosNotifyFilter::ConstraintInfoSeq +%% Returns : ok | +%% {'EXCEPTION', CosNotifyFilter::InvalidConstraint} | +%% {'EXCEPTION', CosNotifyFilter::ConstraintNotFound} +%%----------------------------------------------------------- +%% The OMG specification (TC Document telecom/98-11-01, chapter +%% 3.2.1.3) states (concerning IDs): +%% +%% "If all input values supplied within a particular invocation +%% of this operation are valid, then the specific constraints +%% identified by the values contained in the first input parameter +%% will be deleted from the list of those encapsulated by the target +%% filter object." +%% +%% Hence, first we must check if all ID's exists before deleting. +modify_constraints(_OE_THIS, State, IDs, AddConstraintInfoSeq) -> + %% The following functions are 'safe', i.e., they do not alter any data. + RemoveConstraintInfoSeq = lookup_constraints(IDs, State), + lookup_constraints(AddConstraintInfoSeq, State), + {NewState, Filters, _Info, AddedEventTSeq} = + try_create_filters(State, AddConstraintInfoSeq), + RemovedEventTSeq = ?InfoSeq2EventTypeSeq(RemoveConstraintInfoSeq), + + %% We cannot change anything before our checks (see above). Hence, + %% do NOT move the following lines above this point. + NewState2 = delete_constraints(IDs, NewState), + +%% The OMG specification (TC Document telecom/98-11-01, chapter +%% 3.2.1.3) states (concerning AddConstraintInfoSeq): +%% +%% "If all input values supplied within a particular invocation of this +%% operation are valid, then the constraint expression associated with the +%% already encapsulated constraint identified by the numeric value contained +%% within each element of the input sequence will be modified to the new +%% constraint expression that is contained within the same sequence element." +%% +%% This, our interpretation, implies that ALL previous data related +%% to each unique ID should be removed and replaced by the new data. + + NewState3 = delete_constraints(AddConstraintInfoSeq, NewState2), + NewState4 = store_filters(NewState3, Filters), + inform_callbacks(?get_AllCallback(NewState4), + AddedEventTSeq, RemovedEventTSeq), + {reply, ok, NewState4}. + +%%----------------------------------------------------------% +%% Function : get_constraints/3 +%% Arguments: IDs - CosNotifyFilter::ConstraintIDSeq +%% Returns : CosNotifyFilter::ConstraintInfoSeq | +%% {'EXCEPTION', CosNotifyFilter::ConstraintNotFound} +%%----------------------------------------------------------- +get_constraints(_OE_THIS, State, IDs) -> + {reply, lookup_constraints(IDs, State), State}. + +%%----------------------------------------------------------% +%% Function : get_all_constraints/2 +%% Arguments: - +%% Returns : CosNotifyFilter::ConstraintInfoSeq +%%----------------------------------------------------------- +get_all_constraints(_OE_THIS, State) -> + {reply, ?get_AllConstraints(State), State}. + +%%----------------------------------------------------------% +%% Function : remove_all_constraints/2 +%% Arguments: - +%% Returns : ok +%%----------------------------------------------------------- +remove_all_constraints(_OE_THIS, State) -> + {reply, ok, ?del_AllConstraints(State)}. + +%%----------------------------------------------------------% +%% Function : destroy/2 +%% Arguments: - +%% Returns : ok +%%----------------------------------------------------------- +destroy(_OE_THIS, State) -> + {stop, normal, ok, State}. + +%%----------------------------------------------------------% +%% Function : match/3 +%% Arguments: Event - #any{} +%% Returns : boolean() | +%% {'EXCEPTION', CosNotifyFilter::UnsupportedFilterableData} +%%----------------------------------------------------------- + +match(_OE_THIS, State, Event) when is_record(Event,'any'), ?is_EmptyFilter(State) -> + {reply, true, State}; +match(_OE_THIS, State, Event) when is_record(Event,'any') -> + match_any_event(State, Event, ?get_ConstraintAllData(State)); +match(_,_,What) -> + orber:dbg("[~p] CosNotifyFilter_Filter:match(~p);~n" + "Not an CORBA::Any", [?LINE, What], ?DEBUG_LEVEL), + corba:raise(#'BAD_PARAM'{completion_status=?COMPLETED_NO}). + +%%----------------------------------------------------------% +%% Function : match_structured/3 +%% Arguments: Event - CosNotification::StructuredEvent +%% Returns : boolean() | +%% {'EXCEPTION', CosNotifyFilter::UnsupportedFilterableData} +%%----------------------------------------------------------- +match_structured(_OE_THIS, State, Event) when + is_record(Event,'CosNotification_StructuredEvent') andalso ?is_EmptyFilter(State) -> + {reply, true, State}; +match_structured(_OE_THIS, State, Event) when + is_record(Event,'CosNotification_StructuredEvent') -> + match_str_event(State, Event, ?get_ConstraintAllData(State)); +match_structured(_,_,What) -> + orber:dbg("[~p] CosNotifyFilter_Filter:match_structured(~p);~n" + "Not a StructuredEvent", [?LINE, What], ?DEBUG_LEVEL), + corba:raise(#'BAD_PARAM'{completion_status=?COMPLETED_NO}). + +%%----------------------------------------------------------* +%% Function : match_typed/3 +%% Arguments: Data - CosNotification::PropertySeq +%% Returns : boolean() | +%% {'EXCEPTION', CosNotifyFilter::UnsupportedFilterableData} +%%----------------------------------------------------------- +match_typed(_OE_THIS, _State, _Data) -> + corba:raise(#'NO_IMPLEMENT'{completion_status=?COMPLETED_NO}). + +%%----------------------------------------------------------% +%% Function : attach_callback/3 +%% Arguments: CB - CosNotifyComm::NotifySubscribe +%% Returns : ID - CosNotifyFilter::CallbackID +%%----------------------------------------------------------- +attach_callback(_OE_THIS, State, CB) -> + 'CosNotification_Common':type_check(CB, 'CosNotifyComm_NotifySubscribe'), + CBID = ?new_Id(State), + {reply, CBID, ?add_Callback(State, CBID, CB)}. + +%%----------------------------------------------------------% +%% Function : detach_callback/3 +%% Arguments: ID - CosNotifyFilter::CallbackID +%% Returns : ok | {'EXCEPTION', CosNotifyFilter::CallbackNotFound} +%%----------------------------------------------------------- +detach_callback(_OE_THIS, State, ID) when is_integer(ID) -> + {reply, ok, ?del_Callback(State, ID)}; +detach_callback(_,_,What) -> + orber:dbg("[~p] CosNotifyFilter_Filter:detach_callback(~p);~n" + "Not an integer", [?LINE, What], ?DEBUG_LEVEL), + corba:raise(#'BAD_PARAM'{completion_status=?COMPLETED_NO}). + +%%----------------------------------------------------------% +%% Function : get_callbacks/2 +%% Arguments: - +%% Returns : CosNotifyFilter::CallbackIDSeq +%%----------------------------------------------------------- +get_callbacks(_OE_THIS, State) -> + {reply, ?get_AllCallbackID(State), State}. + +%%--------------- LOCAL FUNCTIONS ---------------------------- +%% To match callbacks +find_obj({value, {_, Obj}},_) -> Obj; +%% To match constraints +find_obj({value, {Id, Con, _, _, _, Types}}, _) -> + ?create_ConstraintInfo(Types, Con, Id); +find_obj([{_, Tree, tree}|_], tree) -> Tree; +% Left out for now to avoid dialyzer warning. +%find_obj(_,callback) -> {'EXCEPTION', #'CosNotifyFilter_CallbackNotFound'{}}; +find_obj(_,tree) -> undefined; +find_obj(_,constraint) -> error. + +%% Delete a single object. +delete_obj(List,List,callback) -> corba:raise(#'CosNotifyFilter_CallbackNotFound'{}); +delete_obj(List,_,_) -> List. + +%% Delete given object from list and all related objects in DB (parse tree and types). +match_delete(State, Constraints, ID) -> + match_delete(State, Constraints, ID, []). +match_delete(_, [], _, _) -> + error; +match_delete(State, [{ID, _Con, _Which, _WC, Key, _Types}|T], ID, Acc) -> + ?del_Type(State, ID), + ?del_ParseTree(State, Key), + {ok, ?set_Constraints(State, Acc++T)}; +match_delete(State, [H|T], ID, Acc) -> + match_delete(State, T, ID, [H|Acc]). + +%% Remove all data related with constraints; for now, since no other data +%% stored in DB, we do in a rather brutal way. +clear_DB(State) -> + catch ets:delete(State#state.etsR), + State#state{etsR = ets:new(oe_ets, [bag, protected]), constraints=[]}. + +%% Given a list of Constrain IDs we want to find the related constraints. +%% !!!!!! This function may not alter any data in DB in any way !!!!!!!!!! +lookup_constraints(IDs, State) -> + lookup_constraints(IDs, State, []). +lookup_constraints([], _State, Accum) -> + Accum; +lookup_constraints([H|T], State, Accum) + when is_record(H, 'CosNotifyFilter_ConstraintInfo') -> + case ?get_Constraint(State, H#'CosNotifyFilter_ConstraintInfo'.constraint_id) of + error -> + corba:raise(#'CosNotifyFilter_ConstraintNotFound' + {id = H#'CosNotifyFilter_ConstraintInfo'.constraint_id}); + _Con -> + %% We don't need to collect the result since the input already is of + %% the correct type, i.e., ConstraintInfoSeq + lookup_constraints(T, State, Accum) + end; +lookup_constraints([H|T], State, Accum) when is_integer(H) -> + case ?get_Constraint(State,H) of + error -> + corba:raise(#'CosNotifyFilter_ConstraintNotFound'{id=H}); + Con -> + lookup_constraints(T, State, [Con|Accum]) + end; +lookup_constraints(_, _, _) -> + corba:raise(#'BAD_PARAM'{completion_status=?COMPLETED_NO}). + +%% Given a list of Constrain IDs we want to delet the related constraints. +%% We need also to return the ConstraintInfoSeq described related to the +%% given ID's. +delete_constraints([], State) -> + State; +delete_constraints([H|T], State) + when is_record(H, 'CosNotifyFilter_ConstraintInfo') -> + case catch ?del_Constraint(State, + H#'CosNotifyFilter_ConstraintInfo'.constraint_id) of + {ok, NewState} -> + delete_constraints(T, NewState); + Reason -> + orber:dbg("[~p] 'CosNotifyFilter_Filter':modify_constraints().~n" + "Unable to remove: ~p~n" + "Reason: ~p~n", + [?LINE, H, Reason], ?DEBUG_LEVEL), + delete_constraints(T, State) + end; +delete_constraints([H|T], State) -> + case catch ?del_Constraint(State,H) of + {ok, NewState} -> + delete_constraints(T, NewState); + Reason -> + orber:dbg("[~p] 'CosNotifyFilter_Filter':modify_constraints().~n" + "Unable to remove: ~p~n" + "Reason: ~p~n", + [?LINE, H, Reason], ?DEBUG_LEVEL), + delete_constraints(T, State) + end. + +%% Inform all registered callbacks that the constraints have changed. +%% Added and Removed must be a CosNotification::EventTypeSeq +inform_callbacks([],_,_) -> + ok; +inform_callbacks([H|T], Added, Removed) -> + case catch 'CosNotifyComm_NotifySubscribe':subscription_change(H, Added, Removed) of + ok -> + ?debug_print("INFORMED CALLBACK: ~p ADDED: ~p REMOVED: ~p", + [H, Added, Removed]), + inform_callbacks(T, Added, Removed); + Other -> + orber:dbg("[~p] 'CosNotifyComm_NotifySubscribe':subscription_change().~n" + "Unable to inform callback: ~p~n" + "Reason: ~p~n", + [?LINE, H, Other], ?DEBUG_LEVEL), + inform_callbacks(T, Added, Removed) + end. + +%%----------------------------------------------------------- +%% Function : try_create_filters/2 +%% Arguments: CL - #'CosNotifyFilter_ConstraintExp'{ +%% event_types = [#'CosNotification_EventType'{ +%% domain_name = Str, type_name = Str}] +%% constraint_expr = Str} +%% Returns : {State, AccumList} +%%----------------------------------------------------------- +%% !!!!!! This function may not alter any data in DB in any way !!!!!!!!!! +try_create_filters(State, CL) -> + try_create_filters(State, CL, [], [], []). +try_create_filters(State, [], Accum, InfoSeq, EventTSeq) -> + {State, Accum, InfoSeq, EventTSeq}; +try_create_filters(State, [#'CosNotifyFilter_ConstraintExp'{event_types = Types, + constraint_expr = Con}|T], + Accum, InfoSeq, EventTSeq) -> + case catch cosNotification_Filter:create_filter(Con) of + {ok, Tree} -> + case catch cosNotification_Filter:check_types(Types) of + true -> + ID = ?new_Id(State), + Key = ?not_CreateDBKey, + NewETSeq = Types ++ EventTSeq, + try_create_filters(?set_IdCounter(State, ID), T, + [{ID, true, [], Key, Types, Con, Tree}|Accum], + [?create_ConstraintInfo(Types, Con, ID)|InfoSeq], + NewETSeq); + {ok, Which, WC} -> + ID = ?new_Id(State), + Key = ?not_CreateDBKey, + NewETSeq = Types ++ EventTSeq, + try_create_filters(?set_IdCounter(State, ID), T, + [{ID, Which, WC, Key, Types, Con, Tree}|Accum], + [?create_ConstraintInfo(Types, Con, ID)|InfoSeq], + NewETSeq); + _ -> + corba:raise(#'BAD_PARAM'{completion_status=?COMPLETED_NO}) + end; + _ -> + corba:raise(#'CosNotifyFilter_InvalidConstraint' + {constr = #'CosNotifyFilter_ConstraintExp' + {event_types = Types, constraint_expr = Con}}) + end; +try_create_filters(State, [#'CosNotifyFilter_ConstraintInfo' + {constraint_expression = #'CosNotifyFilter_ConstraintExp' + {event_types = Types, constraint_expr = Con}, + constraint_id=ID}|T], Accum, InfoSeq, EventTSeq) -> + case catch cosNotification_Filter:create_filter(Con) of + {ok, Tree} -> + case catch cosNotification_Filter:check_types(Types) of + true -> + Key = ?not_CreateDBKey, + NewETSeq = Types ++ EventTSeq, + try_create_filters(State, T, + [{ID, true, [], Key, Types, Con, Tree}|Accum], + [?create_ConstraintInfo(Types, Con, ID)|InfoSeq], + NewETSeq); + {ok, Which, WC} -> + Key = ?not_CreateDBKey, + NewETSeq = Types ++ EventTSeq, + try_create_filters(State, T, + [{ID, Which, WC, Key, Types, Con, Tree}|Accum], + [?create_ConstraintInfo(Types, Con, ID)|InfoSeq], + NewETSeq); + _ -> + corba:raise(#'BAD_PARAM'{completion_status=?COMPLETED_NO}) + end; + _ -> + corba:raise(#'CosNotifyFilter_InvalidConstraint' + {constr = #'CosNotifyFilter_ConstraintExp' + {event_types = Types, constraint_expr = Con}}) + end; +try_create_filters(_,_,_,_,_) -> + %% The list contained something else but ConstraintExp. + corba:raise(#'BAD_PARAM'{completion_status=?COMPLETED_NO}). + +%%----------------------------------------------------------- +%% Function : store_filters/4 +%% Arguments: Filters - a list of filters. +%% Returns : +%%----------------------------------------------------------- + +store_filters(State, []) -> + State; +store_filters(State, [{ID, Which, WC, Key, Types, Con, Tree}|T]) -> + ?add_ParseTree(State, Key, Tree), + write_types(State, Types, ID, Key), + store_filters(?add_Constraint(State, ID, Con, Which, WC, Key, Types), T). + + +write_types(_State, [],_, _) -> + ok; +write_types(State, [EventType|T], ID, Key) -> + ?add_Type(State, ID, EventType, Key), + ?debug_print("FILTER: ~p ~p ~p~n", [ID, Key, EventType]), + write_types(State, T, ID, Key). + +%%----------------------------------------------------------- +%% Function : match_any_event +%% Arguments: +%% Returns : +%%----------------------------------------------------------- +match_any_event(State, _Event, []) -> + ?debug_print("FILTER REJECTED: ~p~n", [_Event]), + {reply, false, State}; +match_any_event(State, Event, [{_, _, _, _, Key, _}|T]) -> + case catch cosNotification_Filter:eval(?get_ParseTree(State,Key), Event) of + true -> + ?debug_print("FILTER APPROVED (WC): ~p~n", [Event]), + {reply, true, State}; + _ -> + match_any_event(State, Event, T) + end. + + +%%----------------------------------------------------------- +%% Function : match_str_event +%% Arguments: +%% Returns : +%%----------------------------------------------------------- + +match_str_event(State, _Event, []) -> + ?debug_print("FILTER REJECTED: ~p~n", [_Event]), + {reply, false, State}; +match_str_event(State, Event, [{ID, _Con, Which, WC, Key, _Types}|T]) -> + ET = ((Event#'CosNotification_StructuredEvent'.header) + #'CosNotification_EventHeader'.fixed_header) + #'CosNotification_FixedEventHeader'.event_type, + CheckList = + case Which of + both -> + [ET]; + domain -> + [ET, + ET#'CosNotification_EventType'{type_name=""}, + ET#'CosNotification_EventType'{type_name="*"}]; + type -> + [ET, + ET#'CosNotification_EventType'{domain_name=""}, + ET#'CosNotification_EventType'{domain_name="*"}]; + _ -> + [ET, + ET#'CosNotification_EventType'{type_name=""}, + ET#'CosNotification_EventType'{type_name="*"}, + ET#'CosNotification_EventType'{domain_name=""}, + ET#'CosNotification_EventType'{domain_name="*"}] + end, + case check_DB(State, ID, CheckList) of + false -> + %% No match, may have used wildcards, e.g., "dom*". + case catch cosNotification_Filter:match_types( + ET#'CosNotification_EventType'.domain_name, + ET#'CosNotification_EventType'.type_name, + WC) of + true -> + case catch cosNotification_Filter:eval(?get_ParseTree(State,Key), + Event) of + true -> + ?debug_print("FILTER APPROVED (WC): ~p~n", [Event]), + {reply, true, State}; + _ -> + match_str_event(State, Event, T) + end; + _-> + match_str_event(State, Event, T) + end; + Key -> + case catch cosNotification_Filter:eval(?get_ParseTree(State,Key), + Event) of + true -> + ?debug_print("FILTER APPROVED: ~p~n", [Event]), + {reply, true, State}; + _ -> + match_str_event(State, Event, T) + end + end. + +check_DB(_, _, []) -> + false; +check_DB(State, ID, [H|T]) -> + case ?match_Type(State, ID, H) of + [] -> + check_DB(State, ID, T); + [{_, K, types}|_] -> + K + end. + + +%%--------------- MISC FUNCTIONS, E.G. DEBUGGING ------------- +%%--------------- END OF MODULE ------------------------------ + |