aboutsummaryrefslogtreecommitdiffstats
path: root/lib/cosProperty/src/CosPropertyService_PropertySetDef_impl.erl
diff options
context:
space:
mode:
authorErlang/OTP <[email protected]>2009-11-20 14:54:40 +0000
committerErlang/OTP <[email protected]>2009-11-20 14:54:40 +0000
commit84adefa331c4159d432d22840663c38f155cd4c1 (patch)
treebff9a9c66adda4df2106dfd0e5c053ab182a12bd /lib/cosProperty/src/CosPropertyService_PropertySetDef_impl.erl
downloadotp-84adefa331c4159d432d22840663c38f155cd4c1.tar.gz
otp-84adefa331c4159d432d22840663c38f155cd4c1.tar.bz2
otp-84adefa331c4159d432d22840663c38f155cd4c1.zip
The R13B03 release.OTP_R13B03
Diffstat (limited to 'lib/cosProperty/src/CosPropertyService_PropertySetDef_impl.erl')
-rw-r--r--lib/cosProperty/src/CosPropertyService_PropertySetDef_impl.erl1041
1 files changed, 1041 insertions, 0 deletions
diff --git a/lib/cosProperty/src/CosPropertyService_PropertySetDef_impl.erl b/lib/cosProperty/src/CosPropertyService_PropertySetDef_impl.erl
new file mode 100644
index 0000000000..157b243c53
--- /dev/null
+++ b/lib/cosProperty/src/CosPropertyService_PropertySetDef_impl.erl
@@ -0,0 +1,1041 @@
+%%--------------------------------------------------------------------
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2000-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: CosPropertyService_PropertySetDef_impl.erl
+%% Modified:
+%%
+%%-----------------------------------------------------------------
+%% README:
+%% (1) The OMG specification states that a property name may not
+%% be an empty string (""). We may restrict this further
+%% but there is no reason for that.
+%%-----------------------------------------------------------------
+-module('CosPropertyService_PropertySetDef_impl').
+
+%%----------------------------------------------------------------------
+%% Include files
+%%----------------------------------------------------------------------
+-include_lib("orber/include/corba.hrl").
+-include_lib("orber/src/orber_iiop.hrl").
+-include_lib("cosProperty/include/CosPropertyService.hrl").
+-include("cosProperty.hrl").
+
+%%----------------------------------------------------------------------
+%% External exports
+%%----------------------------------------------------------------------
+%% Mandatory callbacks
+-export([init/1,
+ terminate/2,
+ code_change/3]).
+
+%% Inherrit from CosPropertyService::PropertySet
+-export([define_property/4,
+ define_properties/3,
+ get_number_of_properties/2,
+ get_all_property_names/3,
+ get_property_value/3,
+ get_properties/3,
+ get_all_properties/3,
+ delete_property/3,
+ delete_properties/3,
+ delete_all_properties/2,
+ is_property_defined/3]).
+
+%% CosPropertyService::PropertySetDef
+-export([get_allowed_property_types/2,
+ get_allowed_properties/2,
+ define_property_with_mode/5,
+ define_properties_with_modes/3,
+ get_property_mode/3,
+ get_property_modes/3,
+ set_property_mode/4,
+ set_property_modes/3]).
+
+%%----------------------------------------------------------------------
+%% Internal exports
+%%----------------------------------------------------------------------
+-export([dump/0]).
+
+%%----------------------------------------------------------------------
+%% Records
+%%----------------------------------------------------------------------
+-record(state, {dbKey, defaultMode, okTypes, okProperties, myType}).
+
+%%----------------------------------------------------------------------
+%% Macros
+%%----------------------------------------------------------------------
+
+-define(create_InitState(K, D, AT, AP, MT), #state{dbKey = K, defaultMode = D,
+ okTypes = AT, okProperties = AP,
+ myType = MT}).
+%% Selectors
+-define(get_DBKey(S), S#state.dbKey).
+-define(get_DefaultMode(S), S#state.defaultMode).
+-define(get_okTypes(S), S#state.okTypes).
+-define(get_okProperties(S), S#state.okProperties).
+%% MISC
+-define(is_NotSetDef(S), S#state.myType =/= ?PropertySetDef).
+-define(no_PropertyLimits(S), S#state.okProperties == []).
+-define(no_TypeLimits(S), S#state.okTypes == []).
+-define(is_NotStatic(S), is_binary(S#state.dbKey)).
+
+%% Fun:s
+-define(Local2Property, fun({N,V,_M}) ->
+ #'CosPropertyService_Property'{property_name = N,
+ property_value = V}
+ end).
+-define(Local2Names, fun({N,_V,_M}) ->
+ N
+ end).
+-define(MemberName(N), fun(R) ->
+ case R of
+ Property when is_record(R, 'CosPropertyService_Property') ->
+ Property#'CosPropertyService_Property'.property_name == N;
+ PropertyDef when is_record(R, 'CosPropertyService_PropertyDef') ->
+ PropertyDef#'CosPropertyService_PropertyDef'.property_name == N;
+ _->
+ false
+ end
+ end).
+
+%%======================================================================
+%% External functions
+%%======================================================================
+%%----------------------------------------------------------------------
+%% Function : init/1
+%% Description: Initiates the server
+%% Returns : {ok, State} |
+%% {ok, State, Timeout} |
+%% ignore |
+%% {stop, Reason}
+%%----------------------------------------------------------------------
+init({DefMode, AllowedTypes, AllowedProperties, InitProperties, MyType}) ->
+ Key = term_to_binary({now(), node()}),
+ _F = ?write_function(#oe_CosPropertyService{key=Key,
+ properties=InitProperties}),
+ write_result(mnesia:transaction(_F)),
+ {ok, ?create_InitState(Key, DefMode, AllowedTypes, AllowedProperties, MyType)};
+init({static, DefMode, AllowedTypes, AllowedProperties, InitProperties, MyType}) ->
+ {ok, ?create_InitState(InitProperties, DefMode, AllowedTypes,
+ AllowedProperties, MyType)}.
+
+%%---------------------------------------------------------------------%
+%% Function : terminate
+%% Description: Shutdown the server
+%% Returns : any (ignored by gen_server)
+%%----------------------------------------------------------------------
+terminate(_Reason, State) when ?is_NotStatic(State) ->
+ _DF = ?delete_function({oe_CosPropertyService, ?get_DBKey(State)}),
+ catch write_result(mnesia:transaction(_DF)),
+ ok;
+terminate(_Reason, _State) ->
+ ok.
+
+%%---------------------------------------------------------------------%
+%% Function : code_change
+%% Description: Convert process state when code is changed
+%% Returns : {ok, State}
+%%----------------------------------------------------------------------
+code_change(_OldVsn, State, _Extra) ->
+ {ok, State}.
+
+
+%%----------------------------------------------------------------------
+%% Interface CosPropertyService::PropertySet
+%%----------------------------------------------------------------------
+%%---------------------------------------------------------------------%
+%% Function : define_property
+%% Arguments :
+%% Description:
+%% Returns : {ok, State}
+%%----------------------------------------------------------------------
+define_property(_, _, "", _) ->
+ corba:raise(#'CosPropertyService_InvalidPropertyName'{});
+define_property(_OE_This, State, Name, Value) when ?is_NotStatic(State) ->
+ evaluate_property_data(State, Value, Name),
+ _DF =
+ fun() ->
+ case mnesia_read(State) of
+ {'EXCEPTION', E} ->
+ {'EXCEPTION', E};
+ X ->
+ case catch update_property(X, Name, value, Value,
+ ?get_DefaultMode(State)) of
+ {'EXCEPTION', E} when
+ is_record(E, 'CosPropertyService_PropertyNotFound') ->
+ mnesia_write(State, [{Name, Value, ?get_DefaultMode(State)}|X]);
+ {'EXCEPTION', E} ->
+ {'EXCEPTION', E};
+ NewProperties ->
+ mnesia_write(State, NewProperties)
+ end
+ end
+ end,
+ {reply, mnesia_transaction(_DF), State};
+define_property(_OE_This, State, Name, Value) ->
+ evaluate_property_data(State, Value, Name),
+ X = ?get_DBKey(State),
+ case catch update_property(X, Name, value, Value, ?get_DefaultMode(State)) of
+ {'EXCEPTION', E} when is_record(E, 'CosPropertyService_PropertyNotFound') ->
+ corba:raise(#'INTERNAL'{completion_status=?COMPLETED_NO});
+ {'EXCEPTION', E} ->
+ corba:raise(E);
+ _NewProperties ->
+ corba:raise(#'INTERNAL'{completion_status=?COMPLETED_NO})
+ end.
+
+
+%%---------------------------------------------------------------------%
+%% Function : get_property_value
+%% Arguments :
+%% Description:
+%% Returns : {ok, State}
+%%----------------------------------------------------------------------
+get_property_value(_, _, "") ->
+ corba:raise(#'CosPropertyService_InvalidPropertyName'{});
+get_property_value(_OE_THIS, State, Name) ->
+ X = lookup_table(?get_DBKey(State)),
+ {reply, find_property(X, Name, value), State}.
+
+%%---------------------------------------------------------------------%
+%% Function : delete_property
+%% Arguments :
+%% Description:
+%% Returns : {ok, State}
+%%----------------------------------------------------------------------
+delete_property(_, _, "") ->
+ corba:raise(#'CosPropertyService_InvalidPropertyName'{});
+delete_property(_OE_THIS, State, Name) when ?is_NotStatic(State) ->
+ _DF =
+ fun() ->
+ case mnesia_read(State) of
+ {'EXCEPTION', E} ->
+ {'EXCEPTION', E};
+ X ->
+ case catch remove_property(X, Name) of
+ {'EXCEPTION', E} ->
+ {'EXCEPTION', E};
+ NewProperties ->
+ mnesia_write(State, NewProperties)
+ end
+ end
+ end,
+ {reply, mnesia_transaction(_DF), State};
+delete_property(_OE_THIS, State, Name) ->
+ X = lookup_table(?get_DBKey(State)),
+ %% Check the properties; must raise an exception.
+ remove_property(X, Name),
+ %% Something is not correct.
+ corba:raise(#'INTERNAL'{completion_status=?COMPLETED_NO}).
+
+
+%%---------------------------------------------------------------------%
+%% Function : define_properties
+%% Arguments :
+%% Description:
+%% Returns : {ok, State}
+%%----------------------------------------------------------------------
+define_properties(_OE_THIS, State, PropertySeq) when ?is_NotStatic(State) ->
+ {OKProperties, Exc} = evaluate_properties_data(State, PropertySeq),
+ _DF =
+ fun() ->
+ case mnesia_read(State) of
+ {'EXCEPTION', E} ->
+ {'EXCEPTION', E};
+ X ->
+ case catch define_properties_helper(State,
+ OKProperties, X, Exc) of
+ {'EXCEPTION', E} ->
+ {'EXCEPTION', E};
+ NewProperties ->
+ mnesia_write(State, NewProperties)
+ end
+ end
+ end,
+ {reply, mnesia_transaction(_DF), State};
+define_properties(_OE_THIS, State, PropertySeq) ->
+ {OKProperties, Exc} = evaluate_properties_data(State, PropertySeq),
+ X = lookup_table(?get_DBKey(State)),
+ case define_properties_helper(State, OKProperties, X, Exc) of
+ {'EXCEPTION', E} ->
+ corba:raise(E);
+ _ ->
+ corba:raise(#'INTERNAL'{completion_status=?COMPLETED_NO})
+ end.
+
+define_properties_helper(_State, [], NewProperties, []) ->
+ %% No exceptions, insert the properties.
+ NewProperties;
+define_properties_helper(_State, [], _, MultipleExceptions) ->
+ {'EXCEPTION', #'CosPropertyService_MultipleExceptions'{exceptions = MultipleExceptions}};
+define_properties_helper(State, [#'CosPropertyService_Property'
+ {property_name = Name,
+ property_value = Value}|T], Properties, Exc) ->
+ case catch update_property(Properties, Name, value, Value, ?get_DefaultMode(State)) of
+ {'EXCEPTION', E} when is_record(E, 'CosPropertyService_PropertyNotFound') ->
+ define_properties_helper(State, T, [{Name, Value, ?get_DefaultMode(State)}|Properties], Exc);
+ {'EXCEPTION', E} ->
+ define_properties_helper(State, T, Properties,
+ [#'CosPropertyService_PropertyException'
+ {reason = remap_exception(E),
+ failing_property_name = Name}|Exc]);
+ NewProperties ->
+ define_properties_helper(State, T, NewProperties, Exc)
+ end.
+
+%%---------------------------------------------------------------------%
+%% Function : get_number_of_properties
+%% Arguments : -
+%% Description: Returns the number of properties currently associated
+%% with this object.
+%% Returns : {ok, ulong(), State}
+%%----------------------------------------------------------------------
+get_number_of_properties(_OE_THIS, State) ->
+ X = lookup_table(?get_DBKey(State)),
+ {reply, length(X), State}.
+
+%%---------------------------------------------------------------------%
+%% Function : get_all_property_names
+%% Arguments :
+%% Description:
+%% Returns : {ok, State}
+%%----------------------------------------------------------------------
+get_all_property_names(_OE_THIS, State, Max) ->
+ X = lookup_table(?get_DBKey(State)),
+ {reply, get_all_property_names_helper(X, [], Max), State}.
+
+get_all_property_names_helper([], Acc, _) ->
+ %% There are no more properties; return a nil-object refernce.
+ {ok, Acc, corba:create_nil_objref()};
+get_all_property_names_helper(Left, Acc, 0) ->
+ %% There are more properties; create Name Iterartor.
+ PropertyNames = lists:map(?Local2Names, Left),
+ {ok, Acc, cosProperty:start_PropertyNamesIterator(PropertyNames)};
+get_all_property_names_helper([{Name, _, _}|T], Acc, No) ->
+ get_all_property_names_helper(T, [Name|Acc], No-1).
+
+
+%%---------------------------------------------------------------------%
+%% Function : get_properties
+%% Arguments : A list of property names, i.e., string()
+%% Description:
+%% Returns : {ok, State}
+%%----------------------------------------------------------------------
+get_properties(_OE_THIS, State, PropertyNames) ->
+ X = lookup_table(?get_DBKey(State)),
+ {reply, locate_names(PropertyNames, X, true, []), State}.
+
+locate_names([], _, AllOK, Acc) ->
+ {AllOK, Acc};
+locate_names([""|T], X, _AllOK, Acc) ->
+ locate_names(T, X, false, [#'CosPropertyService_Property'
+ {property_name = "",
+ property_value =
+ any:create(tk_void, ok)}|Acc]);
+locate_names([H|T], X, AllOK, Acc) ->
+ case catch find_property(X, H, value) of
+ {'EXCEPTION', _} ->
+ locate_names(T, X, false, [#'CosPropertyService_Property'
+ {property_name = H,
+ property_value =
+ any:create(tk_void, ok)}|Acc]);
+ Val ->
+ locate_names(T, X, AllOK, [#'CosPropertyService_Property'
+ {property_name = H,
+ property_value = Val}|Acc])
+ end.
+
+%%---------------------------------------------------------------------%
+%% Function : get_all_properties
+%% Arguments :
+%% Description:
+%% Returns : {ok, State}
+%%----------------------------------------------------------------------
+get_all_properties(_OE_THIS, State, Max) ->
+ X = lookup_table(?get_DBKey(State)),
+ {reply, get_all_properties_helper(X, [], Max), State}.
+
+get_all_properties_helper([], Acc, _) ->
+%% There are no more properties; return a nil-object refernce.
+ {ok, Acc, corba:create_nil_objref()};
+get_all_properties_helper(Left, Acc, 0) ->
+ %% There are more properties; create Iterartor.
+ Properties = lists:map(?Local2Property, Left),
+ {ok, Acc, cosProperty:start_PropertiesIterator(Properties)};
+get_all_properties_helper([{Name, Val, _}|T], Acc, No) ->
+ get_all_properties_helper(T, [#'CosPropertyService_Property'
+ {property_name = Name,
+ property_value = Val}|Acc], No-1).
+
+%%---------------------------------------------------------------------%
+%% Function : delete_properties
+%% Arguments :
+%% Description:
+%% Returns : {ok, State}
+%%----------------------------------------------------------------------
+delete_properties(_OE_THIS, State, []) ->
+ {reply, ok, State};
+delete_properties(_OE_THIS, State, PropertyNames) when ?is_NotStatic(State) ->
+ _DF =
+ fun() ->
+ case mnesia_read(State) of
+ {'EXCEPTION', E} ->
+ {'EXCEPTION', E};
+ X ->
+ case catch delete_properties_helper(X, [], [],
+ PropertyNames, State,
+ length(X)) of
+ {'EXCEPTION', E} ->
+ {'EXCEPTION', E};
+ {{'EXCEPTION', E}, NotDeleted} ->
+ ok = mnesia_write(State, NotDeleted),
+ {'EXCEPTION', E};
+ {ok, NotDeleted} ->
+ mnesia_write(State, NotDeleted)
+ end
+ end
+ end,
+ {reply, mnesia_transaction(_DF), State};
+delete_properties(_OE_THIS, State, PropertyNames) ->
+ X = lookup_table(?get_DBKey(State)),
+ case delete_properties_helper(X, [], [], PropertyNames, State, length(X)) of
+ {'EXCEPTION', E} ->
+ corba:raise(E);
+ _->
+ %% Not acceptable if it was possible to delete one or more Properties.
+ corba:raise(#'INTERNAL'{completion_status=?COMPLETED_NO})
+ end.
+
+delete_properties_helper([], [], NotDeleted, [], _State, _Len) ->
+ %% Since there are no exceptions we have been able to delete all
+ %% properties.
+ {ok, NotDeleted};
+delete_properties_helper([], MultipleExc, NotDeleted, Names, _State, Len) ->
+ %% Write remaining events to DB.
+ case length(NotDeleted) of
+ Len ->
+ {'EXCEPTION', #'CosPropertyService_MultipleExceptions'
+ {exceptions = add_not_found(Names, MultipleExc)}};
+ _->
+ {{'EXCEPTION', #'CosPropertyService_MultipleExceptions'
+ {exceptions = add_not_found(Names, MultipleExc)}},
+ NotDeleted}
+ end;
+delete_properties_helper([{Name, Val, Mode}|T], MultipleExc, NotDeleted,
+ Names, State, Len) ->
+ case lists:member(Name, Names) of
+ true when Mode =/= fixed_normal, Mode =/= fixed_readonly ->
+ delete_properties_helper(T, MultipleExc, NotDeleted,
+ lists:delete(Name, Names), State, Len);
+ true ->
+ delete_properties_helper(T, [#'CosPropertyService_PropertyException'
+ {reason = fixed_property,
+ failing_property_name = Name}|MultipleExc],
+ [{Name, Val, Mode}|NotDeleted],
+ lists:delete(Name, Names), State, Len);
+ false ->
+ delete_properties_helper(T, MultipleExc, [{Name, Val, Mode}|NotDeleted],
+ Names, State, Len)
+ end.
+
+add_not_found([], MultipleExc) ->
+ MultipleExc;
+add_not_found([Name|T], MultipleExc) ->
+ add_not_found(T, [#'CosPropertyService_PropertyException'
+ {reason = property_not_found,
+ failing_property_name = Name}|MultipleExc]).
+
+
+
+%%---------------------------------------------------------------------%
+%% Function : delete_all_properties
+%% Arguments :
+%% Description:
+%% Returns : {ok, State}
+%%----------------------------------------------------------------------
+delete_all_properties(_OE_THIS, State) when ?is_NotStatic(State) ->
+ _DF =
+ fun() ->
+ case mnesia_read(State) of
+ {'EXCEPTION', E} ->
+ {'EXCEPTION', E};
+ X ->
+ case catch delete_all_properties_helper(X, [], State,
+ length(X)) of
+ {'EXCEPTION', E} ->
+ {'EXCEPTION', E};
+ true ->
+ ok = mnesia_write(State, []),
+ true;
+ false ->
+ false;
+ {false, NotDeleted} ->
+ ok = mnesia_write(State, NotDeleted),
+ false
+ end
+ end
+ end,
+ {reply, mnesia_transaction(_DF), State};
+delete_all_properties(_OE_THIS, State) ->
+ X = lookup_table(?get_DBKey(State)),
+ case delete_all_properties_helper(X, [], State, length(X)) of
+ false ->
+ {reply, false, State};
+ _->
+ corba:raise(#'INTERNAL'{completion_status=?COMPLETED_NO})
+ end.
+
+delete_all_properties_helper([], [], _State, _) ->
+ %% Was able to delete all properties.
+ true;
+delete_all_properties_helper([], NotDeleted, _State, Len) ->
+ %% Write remaining events to DB.
+ case length(NotDeleted) of
+ Len ->
+ false;
+ _->
+ {false, NotDeleted}
+ end;
+delete_all_properties_helper([{Name, Val, fixed_normal}|T], NotDeleted, State, Len) ->
+ delete_all_properties_helper(T, [{Name, Val, fixed_normal}|NotDeleted], State, Len);
+delete_all_properties_helper([{Name, Val, fixed_readonly}|T], NotDeleted, State, Len) ->
+ delete_all_properties_helper(T, [{Name, Val, fixed_readonly}|NotDeleted], State, Len);
+delete_all_properties_helper([_|T], NotDeleted, State, Len) ->
+ delete_all_properties_helper(T, NotDeleted, State, Len).
+
+%%---------------------------------------------------------------------%
+%% Function : is_property_defined
+%% Arguments :
+%% Description:
+%% Returns : {ok, State}
+%%----------------------------------------------------------------------
+is_property_defined(_, _, "") ->
+ corba:raise(#'CosPropertyService_InvalidPropertyName'{});
+is_property_defined(_OE_THIS, State, Name) ->
+ X = lookup_table(?get_DBKey(State)),
+ {reply, lists:keymember(Name, 1, X), State}.
+
+%%----------------------------------------------------------------------
+%% Interface CosPropertyService::PropertySetDef
+%%----------------------------------------------------------------------
+%%---------------------------------------------------------------------%
+%% Function : get_allowed_property_types
+%% Arguments : -
+%% Description: Returns the initially supplied restrictions. An empty
+%% list means no restrictions.
+%% Returns : {ok, TypeCodeList,State}
+%%----------------------------------------------------------------------
+get_allowed_property_types(_OE_THIS, State) when ?is_NotSetDef(State) ->
+ corba:raise(#'NO_IMPLEMENT'{completion_status=?COMPLETED_NO});
+get_allowed_property_types(_OE_THIS, State) ->
+ {reply, {ok, ?get_okTypes(State)}, State}.
+
+%%---------------------------------------------------------------------%
+%% Function : get_allowed_properties
+%% Arguments :
+%% Description: Returns the initially supplied restrictions. An empty
+%% list means no restrictions.
+%% Returns : {ok, PropertyDefList, State}
+%%----------------------------------------------------------------------
+get_allowed_properties(_OE_THIS, State) when ?is_NotSetDef(State) ->
+ corba:raise(#'NO_IMPLEMENT'{completion_status=?COMPLETED_NO});
+get_allowed_properties(_OE_THIS, State) ->
+ {reply, {ok, ?get_okProperties(State)}, State}.
+
+%%---------------------------------------------------------------------%
+%% Function : define_property_with_mode
+%% Arguments :
+%% Description:
+%% Returns : {ok, State}
+%%----------------------------------------------------------------------
+define_property_with_mode(_OE_THIS, State, _, _, _) when ?is_NotSetDef(State) ->
+ corba:raise(#'NO_IMPLEMENT'{completion_status=?COMPLETED_NO});
+define_property_with_mode(_, _, "", _, _) ->
+ corba:raise(#'CosPropertyService_InvalidPropertyName'{});
+define_property_with_mode(_OE_THIS, State, Name, Value, Mode)
+ when ?is_NotStatic(State) ->
+ evaluate_property_data(State, Value, Name),
+ _DF =
+ fun() ->
+ case mnesia_read(State) of
+ {'EXCEPTION', E} ->
+ {'EXCEPTION', E};
+ X ->
+ case catch update_property(X, Name, both, Value, Mode) of
+ {'EXCEPTION', E}
+ when is_record(E, 'CosPropertyService_PropertyNotFound') ->
+ mnesia_write(State, [{Name, Value, Mode}|X]);
+ {'EXCEPTION', E} ->
+ {'EXCEPTION', E};
+ NewProperties ->
+ mnesia_write(State, NewProperties)
+ end
+ end
+ end,
+ {reply, mnesia_transaction(_DF), State};
+define_property_with_mode(_OE_THIS, State, Name, Value, Mode) ->
+ evaluate_property_data(State, Value, Name),
+ X = lookup_table(?get_DBKey(State)),
+ case catch update_property(X, Name, both, Value, Mode) of
+ {'EXCEPTION', E} when is_record(E, 'CosPropertyService_PropertyNotFound') ->
+ %% Should get not allowed exception.
+ corba:raise(#'INTERNAL'{completion_status=?COMPLETED_NO});
+ {'EXCEPTION', E} ->
+ corba:raise(E);
+ _ ->
+ %% Should be impossible.
+ corba:raise(#'INTERNAL'{completion_status=?COMPLETED_NO})
+ end.
+
+%%---------------------------------------------------------------------%
+%% Function : define_properties_with_modes
+%% Arguments :
+%% Description:
+%% Returns : {ok, State}
+%%----------------------------------------------------------------------
+define_properties_with_modes(_OE_THIS, State, _) when ?is_NotSetDef(State) ->
+ corba:raise(#'NO_IMPLEMENT'{completion_status=?COMPLETED_NO});
+define_properties_with_modes(_OE_THIS, State, PropertyDefSeq)
+ when ?is_NotStatic(State)->
+ {OKProperteDefs, Exc} = evaluate_properties_data(State, PropertyDefSeq),
+ _DF =
+ fun() ->
+ case mnesia_read(State) of
+ {'EXCEPTION', E} ->
+ {'EXCEPTION', E};
+ X ->
+ case catch define_properties_with_modes_helper(OKProperteDefs,
+ X, Exc, State) of
+ {'EXCEPTION', E} ->
+ {'EXCEPTION', E};
+ NewProperties ->
+ mnesia_write(State, NewProperties)
+ end
+ end
+ end,
+ {reply, mnesia_transaction(_DF), State};
+define_properties_with_modes(_OE_THIS, State, PropertyDefSeq) ->
+ {OKProperteDefs, Exc} = evaluate_properties_data(State, PropertyDefSeq),
+ X = lookup_table(?get_DBKey(State)),
+ case define_properties_with_modes_helper(OKProperteDefs, X, Exc, State) of
+ {'EXCEPTION', E} ->
+ corba:raise(E);
+ _ ->
+ corba:raise(#'INTERNAL'{completion_status=?COMPLETED_NO})
+ end.
+
+
+define_properties_with_modes_helper([], NewPropertyDefs, [], _State) ->
+ %% No exceptions found.
+ NewPropertyDefs;
+define_properties_with_modes_helper([], _, Exc, _) ->
+ {'EXCEPTION', #'CosPropertyService_MultipleExceptions'{exceptions = Exc}};
+define_properties_with_modes_helper([#'CosPropertyService_PropertyDef'
+ {property_name = Name,
+ property_value = Value,
+ property_mode = Mode}|T], X, Exc, State) ->
+ case catch update_property(X, Name, both, Value, Mode) of
+ {'EXCEPTION', E} when is_record(E, 'CosPropertyService_PropertyNotFound') ->
+ define_properties_with_modes_helper(T, [{Name, Value, Mode}|X], Exc, State);
+ {'EXCEPTION', E} ->
+ define_properties_with_modes_helper(T, X,
+ [#'CosPropertyService_PropertyException'
+ {reason = remap_exception(E),
+ failing_property_name = Name}|Exc],
+ State);
+ NewX ->
+ define_properties_with_modes_helper(T, NewX, Exc, State)
+ end.
+
+%%---------------------------------------------------------------------%
+%% Function : get_property_mode
+%% Arguments :
+%% Description:
+%% Returns : {ok, State}
+%%----------------------------------------------------------------------
+get_property_mode(_OE_THIS, State, _) when ?is_NotSetDef(State) ->
+ corba:raise(#'NO_IMPLEMENT'{completion_status=?COMPLETED_NO});
+get_property_mode(_, _, "") ->
+ corba:raise(#'CosPropertyService_InvalidPropertyName'{});
+get_property_mode(_OE_THIS, State, Name) ->
+ X = lookup_table(?get_DBKey(State)),
+ {reply, find_property(X, Name, mode), State}.
+
+%%---------------------------------------------------------------------%
+%% Function : get_property_modes
+%% Arguments :
+%% Description:
+%% Returns : {ok, State}
+%%----------------------------------------------------------------------
+get_property_modes(_OE_THIS, State, _) when ?is_NotSetDef(State) ->
+ corba:raise(#'NO_IMPLEMENT'{completion_status=?COMPLETED_NO});
+get_property_modes(_OE_THIS, State, PropertyNames) ->
+ X = lookup_table(?get_DBKey(State)),
+ {reply, get_property_modes_helper(PropertyNames, X, [], true), State}.
+
+get_property_modes_helper([], _, Acc, Bool) ->
+ {Bool, Acc};
+get_property_modes_helper([""|T], Properties, Acc, _) ->
+ get_property_modes_helper(T, Properties,
+ [#'CosPropertyService_PropertyMode'
+ {property_name = "",
+ property_mode = undefined}|Acc], false);
+get_property_modes_helper([Name|T], Properties, Acc, Bool) ->
+ case lists:keysearch(Name, 1, Properties) of
+ {value, {Name, _, Mode}} ->
+ get_property_modes_helper(T, Properties,
+ [#'CosPropertyService_PropertyMode'
+ {property_name = Name,
+ property_mode = Mode}|Acc], Bool);
+ false ->
+ get_property_modes_helper(T, Properties,
+ [#'CosPropertyService_PropertyMode'
+ {property_name = Name,
+ property_mode = undefined}|Acc], false)
+ end.
+
+%%---------------------------------------------------------------------%
+%% Function : set_property_mode
+%% Arguments :
+%% Description:
+%% Returns : {ok, State}
+%%----------------------------------------------------------------------
+set_property_mode(_OE_THIS, State, _, _) when ?is_NotSetDef(State) ->
+ corba:raise(#'NO_IMPLEMENT'{completion_status=?COMPLETED_NO});
+set_property_mode(_, _, "", _) ->
+ corba:raise(#'CosPropertyService_InvalidPropertyName'{});
+set_property_mode(_OE_THIS, State, Name, Mode) when ?is_NotStatic(State) ->
+ _DF =
+ fun() ->
+ case mnesia_read(State) of
+ {'EXCEPTION', E} ->
+ {'EXCEPTION', E};
+ X ->
+ case catch update_property(X, Name, mode, undefined, Mode) of
+ {'EXCEPTION', E} ->
+ {'EXCEPTION', E};
+ NewProperties ->
+ mnesia_write(State, NewProperties)
+ end
+ end
+ end,
+ {reply, mnesia_transaction(_DF), State};
+set_property_mode(_OE_THIS, State, Name, Mode) ->
+ X = lookup_table(?get_DBKey(State)),
+ update_property(X, Name, mode, undefined, Mode),
+ %% Something is not correct, shouldn't be allowed to update a property when
+ %% static.
+ corba:raise(#'INTERNAL'{completion_status=?COMPLETED_NO}).
+
+%%---------------------------------------------------------------------%
+%% Function : set_property_modes
+%% Arguments :
+%% Description:
+%% Returns : {ok, State}
+%%----------------------------------------------------------------------
+set_property_modes(_OE_THIS, State, _) when ?is_NotSetDef(State) ->
+ corba:raise(#'NO_IMPLEMENT'{completion_status=?COMPLETED_NO});
+set_property_modes(_OE_THIS, State, PropertyModes) when ?is_NotStatic(State) ->
+ _DF =
+ fun() ->
+ case mnesia_read(State) of
+ {'EXCEPTION', E} ->
+ {'EXCEPTION', E};
+ X ->
+ case catch set_property_modes_helper(PropertyModes, X, [],
+ State) of
+ {'EXCEPTION', E} ->
+ {'EXCEPTION', E};
+ NewProperties ->
+ mnesia_write(State, NewProperties)
+ end
+ end
+ end,
+ {reply, mnesia_transaction(_DF), State};
+set_property_modes(_OE_THIS, State, PropertyModes) ->
+ X = lookup_table(?get_DBKey(State)),
+ case set_property_modes_helper(PropertyModes, X, [], State) of
+ {'EXCEPTION', E} ->
+ corba:raise(E);
+ _ ->
+ corba:raise(#'INTERNAL'{completion_status=?COMPLETED_NO})
+ end.
+
+set_property_modes_helper([], NewProperties, [], _State) ->
+ %% No exceptions, write to DB.
+ NewProperties;
+set_property_modes_helper([], _, Exc, _) ->
+ {'EXCEPTION', #'CosPropertyService_MultipleExceptions'{exceptions = Exc}};
+set_property_modes_helper([#'CosPropertyService_PropertyMode'
+ {property_name = Name,
+ property_mode = Mode}|T], X, Exc, State) ->
+ case catch update_property(X, Name, mode, undefined, Mode) of
+ {'EXCEPTION', E} ->
+ set_property_modes_helper(T, X,
+ [#'CosPropertyService_PropertyException'
+ {reason = remap_exception(E),
+ failing_property_name = Name}|Exc],
+ State);
+ NewX ->
+ set_property_modes_helper(T, NewX, Exc, State)
+ end.
+
+
+%%======================================================================
+%% Internal functions
+%%======================================================================
+
+remap_exception(#'CosPropertyService_ConflictingProperty'{}) -> conflicting_property;
+remap_exception(#'CosPropertyService_FixedProperty'{}) -> fixed_property;
+remap_exception(#'CosPropertyService_InvalidPropertyName'{}) -> invalid_property_name;
+remap_exception(#'CosPropertyService_PropertyNotFound'{}) -> property_not_found;
+remap_exception(#'CosPropertyService_UnsupportedTypeCode'{}) -> unsupported_type_code;
+remap_exception(#'CosPropertyService_UnsupportedProperty'{}) -> unsupported_property;
+remap_exception(#'CosPropertyService_ReadOnlyProperty'{}) -> read_only_property;
+remap_exception(#'CosPropertyService_UnsupportedMode'{}) -> unsupported_mode.
+
+find_property([], _, _) ->
+ corba:raise(#'CosPropertyService_PropertyNotFound'{});
+find_property([{Name, Value, _}|_], Name, value) ->
+ Value;
+find_property([{Name, _, Mode}|_], Name, mode) ->
+ Mode;
+% Left out for now to avoid dialyzer warning.
+%find_property([{Name, Value, Mode}|_], Name, all) ->
+% {Name, Value, Mode};
+find_property([_|T], Name, Which) ->
+ find_property(T, Name, Which).
+
+remove_property(PropertList, Name) ->
+ remove_property(PropertList, Name, []).
+remove_property([], _, _) ->
+ corba:raise(#'CosPropertyService_PropertyNotFound'{});
+remove_property([{Name, _, fixed_normal}|_T], Name, _) ->
+ corba:raise(#'CosPropertyService_FixedProperty'{});
+remove_property([{Name, _, fixed_readonly}|_T], Name, _) ->
+ corba:raise(#'CosPropertyService_FixedProperty'{});
+remove_property([{Name, _, _}|T], Name, Acc) ->
+ T++Acc;
+remove_property([H|T], Name, Acc) ->
+ remove_property(T, Name, [H|Acc]).
+
+
+update_property(_, "", _, _, _) ->
+ corba:raise(#'CosPropertyService_InvalidPropertyName'{});
+update_property(PropertyList, Name, Which, Value, Mode) ->
+ update_property(PropertyList, Name, Which, Value, Mode, []).
+
+update_property([], _, _, _, _, _) ->
+ corba:raise(#'CosPropertyService_PropertyNotFound'{});
+update_property([{Name, _, fixed_readonly}|_], Name, value, _, _, _) ->
+ corba:raise(#'CosPropertyService_FixedProperty'{});
+update_property([{Name, _, fixed_normal}|_], Name, both, _, _, _) ->
+ corba:raise(#'CosPropertyService_FixedProperty'{});
+update_property([{Name, _, fixed_readonly}|_], Name, both, _, _, _) ->
+ corba:raise(#'CosPropertyService_FixedProperty'{});
+update_property([{Name, #any{typecode = TC}, Mode}|T], Name,
+ value, #any{typecode = TC, value = Value}, _Mod, Acc) ->
+ [{Name, #any{typecode = TC, value = Value}, Mode}|T]++Acc;
+update_property([{Name, #any{typecode = TC}, _Mode}|T], Name,
+ both, #any{typecode = TC, value = Value}, Mod, Acc) ->
+ [{Name, #any{typecode = TC, value = Value}, Mod}|T]++Acc;
+update_property([{Name, _, _}|_], Name, value, _, _, _) ->
+ corba:raise(#'CosPropertyService_ConflictingProperty'{});
+update_property([{Name, _, _}|_], Name, both, _, _, _) ->
+ corba:raise(#'CosPropertyService_ConflictingProperty'{});
+%% Normally we don't need to raise an exception for the two following cases but
+%% to be able to manage static Properties we must raise an exception. Well,
+%% on the other hand, why should a user try to change a mode to the same value?!
+%% But we have no other option.
+update_property([{Name, _Value, fixed_normal}|_T], Name, mode, _, fixed_normal, _Acc) ->
+ corba:raise(#'CosPropertyService_FixedProperty'{});
+update_property([{Name, _Value, fixed_readonly}|_T], Name, mode, _, fixed_readonly, _Acc) ->
+ corba:raise(#'CosPropertyService_FixedProperty'{});
+update_property([{Name, _Value, fixed_normal}|_T], Name, mode, _, _Mode, _Acc) ->
+ corba:raise(#'CosPropertyService_UnsupportedMode'{});
+update_property([{Name, _Value, fixed_readonly}|_T], Name, mode, _, _Mode, _Acc) ->
+ corba:raise(#'CosPropertyService_UnsupportedMode'{});
+update_property([{Name, Value, _}|T], Name, mode, _, Mode, Acc) ->
+ [{Name, Value, Mode}|T]++Acc;
+update_property([H|T], Name, Which, Value, Mode, Acc) ->
+ update_property(T, Name, Which, Value, Mode, [H|Acc]).
+
+
+lookup_table(Key) when is_binary(Key) ->
+ _RF = ?read_function({oe_CosPropertyService, Key}),
+ case mnesia:transaction(_RF) of
+ {atomic, [#oe_CosPropertyService{properties=Properties}]} ->
+ Properties;
+ {atomic, []} ->
+ corba:raise(#'OBJECT_NOT_EXIST'{completion_status=?COMPLETED_NO});
+ _Other ->
+ corba:raise(#'INTERNAL'{completion_status=?COMPLETED_NO})
+ end;
+lookup_table(Key) when is_list(Key) ->
+ Key;
+lookup_table(_) ->
+ corba:raise(#'INTERNAL'{completion_status=?COMPLETED_NO}).
+
+mnesia_transaction(Fun) ->
+ case mnesia:transaction(Fun) of
+ {atomic, {'EXCEPTION', E}} ->
+ corba:raise(E);
+ {atomic, ok} ->
+ ok;
+ {atomic, Reply} ->
+ Reply;
+ _Other ->
+ corba:raise(#'INTERNAL'{completion_status=?COMPLETED_NO})
+ end.
+
+mnesia_read(State) ->
+ case mnesia:wread({oe_CosPropertyService, ?get_DBKey(State)}) of
+ [#oe_CosPropertyService{properties = X}] ->
+ X;
+ {atomic, []} ->
+ {'EXCEPTION', #'OBJECT_NOT_EXIST'{completion_status=?COMPLETED_NO}};
+ _Other ->
+ {'EXCEPTION', #'INTERNAL'{completion_status=?COMPLETED_NO}}
+ end.
+
+mnesia_write(State, X) ->
+ mnesia:write(#oe_CosPropertyService{key = ?get_DBKey(State), properties = X}).
+
+%% Check a write transaction
+write_result({atomic,ok}) -> ok;
+write_result(_Foo) ->
+ corba:raise(#'INTERNAL'{completion_status=?COMPLETED_NO}).
+
+evaluate_properties_data(State, PropertySeq) ->
+ evaluate_properties_data(State, PropertySeq, [], []).
+
+evaluate_properties_data(_State, [], OKProperties, Exc) ->
+ {OKProperties, Exc};
+
+evaluate_properties_data(State, [#'CosPropertyService_Property'
+ {property_name = Name,
+ property_value = Value}|T], Acc, Exc) ->
+ case catch evaluate_property_data(State, Value, Name) of
+ ok ->
+ evaluate_properties_data(State, T, [#'CosPropertyService_Property'
+ {property_name = Name,
+ property_value = Value}|Acc], Exc);
+ {'EXCEPTION', E} when is_record(E, 'CosPropertyService_UnsupportedTypeCode') ->
+ evaluate_properties_data(State, T, Acc,
+ [#'CosPropertyService_PropertyException'
+ {reason = unsupported_type_code,
+ failing_property_name = Name}|Exc]);
+ {'EXCEPTION', E} when is_record(E, 'CosPropertyService_UnsupportedProperty') ->
+ evaluate_properties_data(State, T, Acc,
+ [#'CosPropertyService_PropertyException'
+ {reason = unsupported_property,
+ failing_property_name = Name}|Exc])
+ end;
+evaluate_properties_data(State, [#'CosPropertyService_PropertyDef'
+ {property_name = Name,
+ property_value = Value,
+ property_mode = Mode}|T], Acc, Exc) ->
+ case catch evaluate_property_data(State, Value, Name) of
+ ok ->
+ evaluate_properties_data(State, T, [#'CosPropertyService_PropertyDef'
+ {property_name = Name,
+ property_value = Value,
+ property_mode = Mode}|Acc], Exc);
+ {'EXCEPTION', E} when is_record(E, 'CosPropertyService_UnsupportedTypeCode') ->
+ evaluate_properties_data(State, T, Acc,
+ [#'CosPropertyService_PropertyException'
+ {reason = unsupported_type_code,
+ failing_property_name = Name}|Exc]);
+ {'EXCEPTION', E} when is_record(E, 'CosPropertyService_UnsupportedProperty') ->
+ evaluate_properties_data(State, T, Acc,
+ [#'CosPropertyService_PropertyException'
+ {reason = unsupported_property,
+ failing_property_name = Name}|Exc])
+ end;
+evaluate_properties_data(_, _, _, _) ->
+ corba:raise(#'BAD_PARAM'{completion_status=?COMPLETED_NO}).
+
+evaluate_property_data(State, _, _) when ?no_PropertyLimits(State),
+ ?no_TypeLimits(State) ->
+ ok;
+evaluate_property_data(State, Value, _Name) when ?no_PropertyLimits(State) ->
+ case lists:member(any:get_typecode(Value), ?get_okTypes(State)) of
+ true ->
+ ok;
+ _ ->
+ corba:raise(#'CosPropertyService_UnsupportedTypeCode'{})
+ end;
+evaluate_property_data(State, _Value, Name) when ?no_TypeLimits(State) ->
+ case lists:any(?MemberName(Name), ?get_okProperties(State)) of
+ true ->
+ ok;
+ _ ->
+ corba:raise(#'CosPropertyService_UnsupportedProperty'{})
+ end;
+evaluate_property_data(State, Value, Name) ->
+ case lists:any(?MemberName(Name), ?get_okProperties(State)) of
+ true ->
+ case lists:member(any:get_typecode(Value), ?get_okTypes(State)) of
+ true ->
+ ok;
+ _ ->
+ corba:raise(#'CosPropertyService_UnsupportedTypeCode'{})
+ end;
+ _ ->
+ corba:raise(#'CosPropertyService_UnsupportedProperty'{})
+ end.
+
+
+%%----------------------------------------------------------------------
+%% Debugging functions
+%%----------------------------------------------------------------------
+dump() ->
+ case catch mnesia:dirty_first('oe_CosPropertyService') of
+ {'EXIT', R} ->
+ io:format("Exited with ~p\n",[R]);
+ Key ->
+ dump_print(Key),
+ dump_loop(Key)
+ end.
+
+dump_loop(PreviousKey) ->
+ case catch mnesia:dirty_next('oe_CosPropertyService', PreviousKey) of
+ {'EXIT', R} ->
+ io:format("Exited with ~p\n",[R]);
+ '$end_of_table' ->
+ ok;
+ Key ->
+ dump_print(Key),
+ dump_loop(Key)
+ end.
+
+dump_print(Key) ->
+ case catch mnesia:dirty_read({'oe_CosPropertyService', Key}) of
+ {'EXIT', R} ->
+ io:format("Exited with ~p\n",[R]);
+ [{_,_,X}] ->
+ io:format("Property: ~p~n", [X]);
+ _ ->
+ ok
+ end.
+
+
+%%-------------------------- END OF MODULE -----------------------------