diff options
Diffstat (limited to 'lib/cosNotification/src/CosNotifyFilter_MappingFilter_impl.erl')
-rw-r--r-- | lib/cosNotification/src/CosNotifyFilter_MappingFilter_impl.erl | 580 |
1 files changed, 0 insertions, 580 deletions
diff --git a/lib/cosNotification/src/CosNotifyFilter_MappingFilter_impl.erl b/lib/cosNotification/src/CosNotifyFilter_MappingFilter_impl.erl deleted file mode 100644 index 03c0e03be6..0000000000 --- a/lib/cosNotification/src/CosNotifyFilter_MappingFilter_impl.erl +++ /dev/null @@ -1,580 +0,0 @@ -%%-------------------------------------------------------------------- -%% -%% %CopyrightBegin% -%% -%% Copyright Ericsson AB 1999-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 : CosNotifyFilter_MappingFilter_impl.erl -%% Purpose : -%%---------------------------------------------------------------------- - --module('CosNotifyFilter_MappingFilter_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, - '_get_value_type'/2, - '_get_default_value'/2]). -%% External Functions --export([add_mapping_constraints/3, - modify_mapping_constraints/4, - get_mapping_constraints/3, - get_all_mapping_constraints/2, - remove_all_mapping_constraints/2, - destroy/2, - match/3, - match_structured/3, - match_typed/3]). - -%%--------------- gen_server specific exports ---------------- --export([handle_info/2, code_change/3]). --export([init/1, terminate/2]). - -%%--------------- LOCAL DEFINITIONS -------------------------- -%%######### MISC ########## --define(create_MappingInfo(_Types, _Con, _ID, _A), - #'CosNotifyFilter_MappingConstraintInfo'{ - constraint_expression = - #'CosNotifyFilter_ConstraintExp'{ - event_types = _Types, - constraint_expr = _Con}, - constraint_id = _ID, - value = _A - }). -%%#### Data structures #### --record(state, {constraint_grammar, - value, - typeC, - constraints = [], - filters = [], - idCounter = 0, - filterFactory, - factoryPid, - etsR}). - -%% Data structures constructors --define(get_InitState(Gr, DVal, FF, FP), - #state{constraint_grammar=Gr, - value = DVal, - typeC = any:get_typecode(DVal), - filterFactory = FF, - factoryPid = FP, - etsR = ets:new(oe_ets, [bag, protected])}). - -%%------------------- Data structures selectors ------------------- -%% Attributes --define(get_Grammar(S), S#state.constraint_grammar). --define(get_DefVal(S), S#state.value). --define(get_DefTC(S), S#state.typeC). --define(get_DefAny(S), S#state.value). - -%% 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, A}) -> - ?create_MappingInfo(T, C, I, A) - 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 ------------------- -%% 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,A), S#state{constraints = - [{I, C, W, _WC, K, T, A}|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(is_EqualType(S,T), S#state.typeC==any:get_typecode(T)). - -%%-----------------------------------------------------------% -%% 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, InitGr, DefVal]) -> - process_flag(trap_exit, true), - {ok, ?get_InitState(InitGr, DefVal, FiFac, FacPid)}. - -terminate(_Reason, _State) -> - ok. - -%%----------------------------------------------------------- -%%------- Exported external attributes ---------------------- -%%----------------------------------------------------------- -%%----------------------------------------------------------% -%% Function : '_get_constraint_grammar'/2 -%% Type : readonly -%% Returns : string() -%%----------------------------------------------------------- -'_get_constraint_grammar'(_OE_THIS, State) -> - {reply, ?get_Grammar(State), State}. -%%----------------------------------------------------------% -%% Function : '_get_value_type'/2 -%% Type : readonly -%% Returns : CORBA::TypeCode -%%----------------------------------------------------------- -'_get_value_type'(_OE_THIS, State) -> - {reply, ?get_DefTC(State), State}. -%%----------------------------------------------------------% -%% Function : '_get_default_value'/2 -%% Type : readonly -%% Returns : #any{} -%%----------------------------------------------------------- -'_get_default_value'(_OE_THIS, State) -> - {reply, ?get_DefVal(State), State}. - -%%----------------------------------------------------------- -%%------- Exported external functions ----------------------- -%%----------------------------------------------------------- -%%----------------------------------------------------------% -%% Function : add_mapping_constraints/3 -%% Arguments: Pairs - CosNotifyFilter::MappingConstraintPairSeq -%% Returns : CosNotifyFilter::MappingConstraintInfoSeq | -%% {'EXCEPTION', CosNotifyFilter::InvalidConstraint} | -%% {'EXCEPTION', CosNotifyFilter::InvalidValue} -%%----------------------------------------------------------- -add_mapping_constraints(_OE_THIS, State, Pairs) -> - {NewState, Filters, Info} = try_create_filters(State, Pairs), - NewState2=store_filters(NewState, Filters), - {reply, Info, NewState2}. - -%%----------------------------------------------------------% -%% Function : modify_mapping_constraints/4 -%% Arguments: IDs - CosNotifyFilter::ConstraintIDSeq -%% Info - CosNotifyFilter::MappingConstraintInfoSeq -%% Returns : ok | -%% {'EXCEPTION', CosNotifyFilter::InvalidConstraint} | -%% {'EXCEPTION', CosNotifyFilter::InvalidValue} | -%% {'EXCEPTION', CosNotifyFilter::ConstraintNotFound} -%%----------------------------------------------------------- -modify_mapping_constraints(_OE_THIS, State, IDs, InfoSeq) -> - lookup_constraints(IDs, State), - lookup_constraints(InfoSeq, State), - {NewState, Filters, _Info} = try_create_filters(State, InfoSeq), - - %% We cannot change anything before our checks (see above). Hence, - %% do NOT move the following lines above this point. - - NewState2 = delete_constraints(IDs, NewState), - NewState3 = delete_constraints(InfoSeq, NewState2), - NewState4 = store_filters(NewState3, Filters), - {reply, ok, NewState4}. - -%%----------------------------------------------------------% -%% Function : get_mapping_constraints/3 -%% Arguments: IDs - CosNotifyFilter::ConstraintIDSeq -%% Returns : CosNotifyFilter::MappingConstraintInfoSeq | -%% {'EXCEPTION', CosNotifyFilter::ConstraintNotFound} -%%----------------------------------------------------------- -get_mapping_constraints(_OE_THIS, State, IDs) -> - {reply, lookup_constraints(IDs, State), State}. - -%%----------------------------------------------------------% -%% Function : get_all_mapping_constraints/2 -%% Arguments: - -%% Returns : CosNotifyFilter::MappingConstraintInfoSeq -%%----------------------------------------------------------- -get_all_mapping_constraints(_OE_THIS, State) -> - {reply, ?get_AllConstraints(State), State}. - -%%----------------------------------------------------------% -%% Function : remove_all_mapping_constraints/2 -%% Arguments: - -%% Returns : ok -%%----------------------------------------------------------- -remove_all_mapping_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(), #any{} (out-type) | -%% {'EXCEPTION', CosNotifyFilter::UnsupportedFilterableData} -%%----------------------------------------------------------- -match(_OE_THIS, State, Event) when is_record(Event,'any') andalso ?is_EmptyFilter(State) -> - {reply, {false, ?get_DefAny(State)}, State}; -match(_OE_THIS, State, Event) when is_record(Event,'any') -> - match_any_event(State, Event, ?get_ConstraintAllData(State)); -match(_,_,_) -> - corba:raise(#'BAD_PARAM'{completion_status=?COMPLETED_NO}). - - -%%----------------------------------------------------------% -%% Function : match_structured/3 -%% Arguments: Event - CosNotification::StructuredEvent -%% Returns : boolean(), #any{} (out-type) | -%% {'EXCEPTION', CosNotifyFilter::UnsupportedFilterableData} -%%----------------------------------------------------------- -match_structured(_OE_THIS, State, Event) when - is_record(Event,'CosNotification_StructuredEvent') andalso ?is_EmptyFilter(State) -> - {reply, {false, ?get_DefAny(State)}, State}; -match_structured(_OE_THIS, State, Event) when - is_record(Event,'CosNotification_StructuredEvent') -> - match_str_event(State, Event, ?get_ConstraintAllData(State)); -match_structured(_,_,_) -> - corba:raise(#'BAD_PARAM'{completion_status=?COMPLETED_NO}). - -%%----------------------------------------------------------* -%% Function : match_typed/3 -%% Arguments: Data - CosNotification::PropertySeq -%% Returns : boolean() , #any{} (out-type) | -%% {'EXCEPTION', CosNotifyFilter::UnsupportedFilterableData} -%%----------------------------------------------------------- --spec match_typed(_, _, _) -> no_return(). -match_typed(_OE_THIS, _State, _Data) -> - corba:raise(#'NO_IMPLEMENT'{completion_status=?COMPLETED_NO}). - -%%--------------- LOCAL FUNCTIONS ---------------------------- -%% To match constraints -find_obj({value, {Id, Con, _, _, _, Types, Any}}, _) -> - ?create_MappingInfo(Types, Con, Id, Any); -find_obj([{_, Tree, tree}|_], tree) -> Tree; -find_obj(_,tree) -> undefined; -find_obj(_,constraint) -> error. - -%% 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, _Any}|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_MappingConstraintInfo') -> - case ?get_Constraint(State, H#'CosNotifyFilter_MappingConstraintInfo'.constraint_id) of - error -> - corba:raise(#'CosNotifyFilter_ConstraintNotFound' - {id = H#'CosNotifyFilter_MappingConstraintInfo'.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_MappingConstraintInfo') -> - case catch ?del_Constraint(State, - H#'CosNotifyFilter_MappingConstraintInfo'.constraint_id) of - {ok, NewState} -> - delete_constraints(T, NewState); - Reason -> - orber:dbg("[~p] 'CosNotifyFilter_MappingFilter':modify_mapping_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_MappingFilter':modify_mapping_constraints().~n" - "Unable to remove: ~p~n" - "Reason: ~p~n", - [?LINE, H, Reason], ?DEBUG_LEVEL), - delete_constraints(T, State) - end. - -%%----------------------------------------------------------- -%% Function : try_create_filters/2 -%% Arguments: CL - #'CosNotifyFilter_MappingConstraintPair{ -%% constraint_expression = -%% #'CosNotifyFilter_ConstraintExp'{ -%% event_types = -%% [#'CosNotification_EventType'{ -%% domain_name = Str, type_name = Str}] -%% constraint_expr = Str}, -%% result_to_set = Any} -%% 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) -> - {State, Accum, InfoSeq}; -try_create_filters(State, [#'CosNotifyFilter_MappingConstraintPair' - {constraint_expression = - #'CosNotifyFilter_ConstraintExp'{event_types = Types, - constraint_expr = Con}, - result_to_set=Any}|T], Accum, InfoSeq) -> - case catch {?is_EqualType(State,Any), cosNotification_Filter:create_filter(Con)} of - {false, _} -> - corba:raise(#'CosNotifyFilter_InvalidValue' - {constr = #'CosNotifyFilter_ConstraintExp' - {event_types = Types, constraint_expr = Con}, - value=Any}); - {_, {ok, Tree}} -> - case catch cosNotification_Filter:check_types(Types) of - true -> - ID = ?new_Id(State), - Key = ?not_CreateDBKey, - try_create_filters(?set_IdCounter(State, ID), T, - [{ID, true, [], Key, Types, Con, Tree, Any}|Accum], - [?create_MappingInfo(Types, Con, ID, Any)|InfoSeq]); - {ok, Which, WC} -> - ID = ?new_Id(State), - Key = ?not_CreateDBKey, - try_create_filters(?set_IdCounter(State, ID), T, - [{ID, Which, WC, Key, Types, Con, Tree, Any}|Accum], - [?create_MappingInfo(Types, Con, ID, Any)|InfoSeq]); - _ -> - 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_MappingConstraintInfo' - {constraint_expression = #'CosNotifyFilter_ConstraintExp' - {event_types = Types, constraint_expr = Con}, - constraint_id=ID, - value=Any}|T], Accum, InfoSeq) -> - case catch cosNotification_Filter:create_filter(Con) of - {ok, Tree} -> - case catch cosNotification_Filter:check_types(Types) of - true -> - Key = ?not_CreateDBKey, - try_create_filters(State, T, - [{ID, true, [], Key, Types, Con, Tree, Any}|Accum], - [?create_MappingInfo(Types, Con, ID, Any)|InfoSeq]); - {ok, Which, WC} -> - Key = ?not_CreateDBKey, - try_create_filters(State, T, - [{ID, Which, WC, Key, Types, Con, Tree, Any}|Accum], - [?create_MappingInfo(Types, Con, ID, Any)|InfoSeq]); - _ -> - 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, Any}|T]) -> - ?add_ParseTree(State, Key, Tree), - write_types(State, Types, ID, Key), - store_filters(?add_Constraint(State, ID, Con, Which, WC, Key, Types, Any), 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: Event - #any{} -%% Returns : -%%----------------------------------------------------------- -match_any_event(State, _Event, []) -> - ?debug_print("FILTER REJECTED: ~p~n", [_Event]), - {reply, {false, ?get_DefAny(State)}, State}; -match_any_event(State, Event, [{_, _, _, _, Key, Any}|T]) -> - case catch cosNotification_Filter:eval(?get_ParseTree(State,Key), Event) of - true -> - ?debug_print("FILTER APPROVED (WC): ~p~n", [Event]), - {reply, {true, Any}, 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, ?get_DefAny(State)}, State}; -match_str_event(State, Event, [{ID, _Con, Which, WC, Key, _Types, Any}|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, Any}, 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, Any}, 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 ------------------------------ - |