diff options
Diffstat (limited to 'lib/cosProperty/src')
-rw-r--r-- | lib/cosProperty/src/CosProperty.cfg | 5 | ||||
-rw-r--r-- | lib/cosProperty/src/CosProperty.idl | 192 | ||||
-rw-r--r-- | lib/cosProperty/src/CosPropertyService_PropertiesIterator_impl.erl | 166 | ||||
-rw-r--r-- | lib/cosProperty/src/CosPropertyService_PropertyNamesIterator_impl.erl | 158 | ||||
-rw-r--r-- | lib/cosProperty/src/CosPropertyService_PropertySetDefFactory_impl.erl | 179 | ||||
-rw-r--r-- | lib/cosProperty/src/CosPropertyService_PropertySetDef_impl.erl | 1041 | ||||
-rw-r--r-- | lib/cosProperty/src/CosPropertyService_PropertySetFactory_impl.erl | 176 | ||||
-rw-r--r-- | lib/cosProperty/src/Makefile | 183 | ||||
-rw-r--r-- | lib/cosProperty/src/cosProperty.app.src | 45 | ||||
-rw-r--r-- | lib/cosProperty/src/cosProperty.appup.src | 6 | ||||
-rw-r--r-- | lib/cosProperty/src/cosProperty.erl | 414 | ||||
-rw-r--r-- | lib/cosProperty/src/cosProperty.hrl | 81 |
12 files changed, 2646 insertions, 0 deletions
diff --git a/lib/cosProperty/src/CosProperty.cfg b/lib/cosProperty/src/CosProperty.cfg new file mode 100644 index 0000000000..f10bf843d6 --- /dev/null +++ b/lib/cosProperty/src/CosProperty.cfg @@ -0,0 +1,5 @@ +{this, "CosPropertyService::PropertySet"}. +{this, "CosPropertyService::PropertySetDef"}. +{this, "CosPropertyService::PropertySetDefFactory"}. +{this, "CosPropertyService::PropertySetFactory"}. + diff --git a/lib/cosProperty/src/CosProperty.idl b/lib/cosProperty/src/CosProperty.idl new file mode 100644 index 0000000000..156fb37ccc --- /dev/null +++ b/lib/cosProperty/src/CosProperty.idl @@ -0,0 +1,192 @@ +#ifndef _COSPROPERTY_IDL +#define _COSPROPERTY_IDL + +#pragma prefix "omg.org" + +module CosPropertyService { + /*****************************************************/ + /* Data Types */ + /*****************************************************/ + typedef string PropertyName; + + struct Property { + PropertyName property_name; + any property_value; + }; + + enum PropertyModeType { + normal, read_only, fixed_normal, fixed_readonly, undefined }; + + struct PropertyDef { + PropertyName property_name; + any property_value; + PropertyModeType property_mode; + }; + + struct PropertyMode { + PropertyName property_name; + PropertyModeType property_mode; + }; + + typedef sequence<PropertyName> PropertyNames; + typedef sequence<Property> Properties; + typedef sequence<PropertyDef> PropertyDefs; + typedef sequence<PropertyMode> PropertyModes; + typedef sequence<CORBA::TypeCode> PropertyTypes; + + interface PropertyNamesIterator; + interface PropertiesIterator; + interface PropertySetFactory; + interface PropertySetDef; + interface PropertySet; + + /*****************************************************/ + /* Exceptions */ + /*****************************************************/ + exception ConstraintNotSupported{}; + exception InvalidPropertyName {}; + exception ConflictingProperty {}; + exception PropertyNotFound {}; + exception UnsupportedTypeCode {}; + exception UnsupportedProperty {}; + exception UnsupportedMode {}; + exception FixedProperty {}; + exception ReadOnlyProperty {}; + + enum ExceptionReason { invalid_property_name, conflicting_property, + property_not_found, unsupported_type_code, + unsupported_property, unsupported_mode, + fixed_property, read_only_property }; + + struct PropertyException { + ExceptionReason reason; + PropertyName failing_property_name; + }; + + typedef sequence<PropertyException> PropertyExceptions; + exception MultipleExceptions { PropertyExceptions exceptions; }; + + /*****************************************************/ + /* Interface Definitions */ + /*****************************************************/ + interface PropertySetFactory { + PropertySet create_propertyset(); + + PropertySet create_constrained_propertyset( in PropertyTypes allowed_property_types, + in Properties allowed_properties) + raises(ConstraintNotSupported); + + PropertySet create_initial_propertyset( in Properties initial_properties) + raises(MultipleExceptions); }; + + /*---------------------------------------------------*/ + interface PropertySetDefFactory { + PropertySetDef create_propertysetdef(); + + PropertySetDef create_constrained_propertysetdef( in PropertyTypes allowed_property_types, + in PropertyDefs allowed_property_defs) + raises(ConstraintNotSupported); + + PropertySetDef create_initial_propertysetdef( in PropertyDefs initial_property_defs) + raises(MultipleExceptions); + }; + + /*---------------------------------------------------*/ + interface PropertySet { + /* Support for defining and modifying properties */ + void define_property( in PropertyName property_name, in any property_value) + raises(InvalidPropertyName, ConflictingProperty, UnsupportedTypeCode, + UnsupportedProperty, ReadOnlyProperty); + + void define_properties( in Properties nproperties) + raises(MultipleExceptions); + + /* Support for Getting Properties and their Names */ + unsigned long get_number_of_properties(); + + void get_all_property_names( in unsigned long how_many, + out PropertyNames property_names, + out PropertyNamesIterator rest); + + any get_property_value( in PropertyName property_name) + raises(PropertyNotFound, InvalidPropertyName); + + boolean get_properties( in PropertyNames property_names, + out Properties nproperties); + + void get_all_properties( in unsigned long how_many, + out Properties nproperties, + out PropertiesIterator rest); + + /* Support for Deleting Properties */ + void delete_property( in PropertyName property_name) + raises(PropertyNotFound, InvalidPropertyName, FixedProperty); + + void delete_properties( in PropertyNames property_names) + raises(MultipleExceptions); + + boolean delete_all_properties(); + + /* Support for Existence Check */ + boolean is_property_defined( in PropertyName property_name) + raises(InvalidPropertyName); + }; + + /*---------------------------------------------------*/ + interface PropertySetDef:PropertySet { + /* Support for retrieval of PropertySet constraints*/ + void get_allowed_property_types( out PropertyTypes property_types); + + void get_allowed_properties( out PropertyDefs property_defs); + + /* Support for defining and modifying properties */ + void define_property_with_mode( in PropertyName property_name, + in any property_value, + in PropertyModeType property_mode) + raises(InvalidPropertyName, ConflictingProperty, UnsupportedTypeCode, + UnsupportedProperty, UnsupportedMode, ReadOnlyProperty); + + void define_properties_with_modes( in PropertyDefs property_defs) + raises(MultipleExceptions); + + /* Support for Getting and Setting Property Modes */ + PropertyModeType get_property_mode( in PropertyName property_name) + raises(PropertyNotFound, InvalidPropertyName); + + boolean get_property_modes( in PropertyNames property_names, + out PropertyModes property_modes); + + void set_property_mode( in PropertyName property_name, + in PropertyModeType property_mode) + raises(InvalidPropertyName, PropertyNotFound, UnsupportedMode); + + void set_property_modes( in PropertyModes property_modes) + raises(MultipleExceptions); + }; + + /*---------------------------------------------------*/ + interface PropertyNamesIterator{ + void reset(); + + boolean next_one( out PropertyName property_name); + + boolean next_n ( in unsigned long how_many, + out PropertyNames property_names); + + void destroy(); + }; + + /*---------------------------------------------------*/ + interface PropertiesIterator { + void reset(); + + boolean next_one( out Property aproperty); + + boolean next_n( in unsigned long how_many, + out Properties nproperties); + + void destroy(); + }; +}; + +#endif diff --git a/lib/cosProperty/src/CosPropertyService_PropertiesIterator_impl.erl b/lib/cosProperty/src/CosPropertyService_PropertiesIterator_impl.erl new file mode 100644 index 0000000000..a7769cea4d --- /dev/null +++ b/lib/cosProperty/src/CosPropertyService_PropertiesIterator_impl.erl @@ -0,0 +1,166 @@ +%%-------------------------------------------------------------------- +%% +%% %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_PropertiesIterator_impl.erl +%% Description : +%% +%%---------------------------------------------------------------------- +-module('CosPropertyService_PropertiesIterator_impl'). + +%%---------------------------------------------------------------------- +%% Include files +%%---------------------------------------------------------------------- +-include_lib("orber/include/corba.hrl"). +-include_lib("orber/src/orber_iiop.hrl"). +-include("CosPropertyService.hrl"). +-include("cosProperty.hrl"). + + +%%---------------------------------------------------------------------- +%% External exports +%%---------------------------------------------------------------------- +%% Mandatory server functions +-export([init/1, + terminate/2, + code_change/3]). + +-export([reset/1, + next_one/1, + next_n/2, + destroy/1]). + +%%---------------------------------------------------------------------- +%% Internal exports +%%---------------------------------------------------------------------- +-export([ + ]). + +%%---------------------------------------------------------------------- +%% Records +%%---------------------------------------------------------------------- +-record(state, {properties, counter=1, length}). + +%%---------------------------------------------------------------------- +%% Macros +%%---------------------------------------------------------------------- +-define(CreateInitState(L), #state{properties = L, length = length(L)}). +-define(get_Properties(S), S#state.properties). +-define(get_Counter(S), S#state.counter). +-define(get_Length(S), S#state.length). + +-define(set_Properties(S, P), S#state{properties = P}). +-define(set_Counter(S, C), S#state{counter = C}). +-define(set_Length(S, L), S#state{length = L}). + +-define(increment_Counter(S), S#state{counter = S#state.counter+1}). +-define(decrement_Counter(S), S#state{counter = S#state.counter-1}). +-define(addto_Counter(S, N), S#state{counter = S#state.counter+N}). +-define(subfrom_Counter(S, N), S#state{counter = S#state.counter-N}). + + +%%====================================================================== +%% External functions +%%====================================================================== +%%---------------------------------------------------------------------- +%% Function : init/1 +%% Description: Initiates the server +%% Returns : {ok, State} | +%% {ok, State, Timeout} | +%% ignore | +%% {stop, Reason} +%%---------------------------------------------------------------------- +init(Properties) -> + {ok, ?CreateInitState(Properties)}. + +%%---------------------------------------------------------------------- +%% Function : terminate/2 +%% Description: Shutdown the server +%% Returns : any (ignored by gen_server) +%%---------------------------------------------------------------------- +terminate(_Reason, _State) -> + ok. + +%%---------------------------------------------------------------------- +%% Function : code_change/3 +%% Description: Convert process state when code is changed +%% Returns : {ok, NewState} +%%---------------------------------------------------------------------- +code_change(_OldVsn, State, _Extra) -> + {ok, State}. + +%%---------------------------------------------------------------------% +%% Function : reset +%% Arguments : - +%% Description: +%% Returns : {ok, NewState} +%%---------------------------------------------------------------------- +reset(State) -> + {reply, ok, ?set_Counter(State, 1)}. + +%%---------------------------------------------------------------------- +%% Function : next_one +%% Arguments : - +%% Description: +%% Returns : {ok, {bool(), PropertyList}, NewState} +%%---------------------------------------------------------------------- +next_one(State) when ?get_Counter(State) > ?get_Length(State) -> + {reply, {false, + #'CosPropertyService_Property' + {property_name = "", + property_value = any:create(orber_tc:null(), null)}}, + State}; +next_one(State) -> + {reply, {true, lists:nth(?get_Counter(State), ?get_Properties(State))}, + ?set_Counter(State, 1+?get_Counter(State))}. + +%%---------------------------------------------------------------------- +%% Function : next_n +%% Arguments : N - how many properties we should return. +%% Description: +%% Returns : {ok, {bool(), PropertyList}, NewState} +%%---------------------------------------------------------------------- +next_n(State, N) -> + case lists:sublist(?get_Properties(State), + ?get_Counter(State), + N) of + Properties when N+?get_Counter(State) < ?get_Length(State) -> + {reply, {true, Properties}, ?set_Counter(State, N+?get_Counter(State))}; + Properties -> + {reply, {false, Properties}, ?set_Counter(State, ?get_Length(State))} + end. + +%%---------------------------------------------------------------------% +%% Function : destroy +%% Arguments : - +%% Description: Terminate the object +%% Returns : {ok, NewState} +%%---------------------------------------------------------------------- +destroy(State) -> + {stop, normal, ok, State}. + +%%====================================================================== +%% Internal functions +%%===================================================================== + +%%====================================================================== +%% END OF MODULE +%%====================================================================== + diff --git a/lib/cosProperty/src/CosPropertyService_PropertyNamesIterator_impl.erl b/lib/cosProperty/src/CosPropertyService_PropertyNamesIterator_impl.erl new file mode 100644 index 0000000000..fc5cddd7c3 --- /dev/null +++ b/lib/cosProperty/src/CosPropertyService_PropertyNamesIterator_impl.erl @@ -0,0 +1,158 @@ +%%-------------------------------------------------------------------- +%% +%% %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_PropertyNamesIterator_impl.erl +%% Description : +%% +%%---------------------------------------------------------------------- +-module('CosPropertyService_PropertyNamesIterator_impl'). + +%%---------------------------------------------------------------------- +%% Include files +%%---------------------------------------------------------------------- +-include_lib("orber/include/corba.hrl"). +-include_lib("orber/src/orber_iiop.hrl"). +-include("CosPropertyService.hrl"). +-include("cosProperty.hrl"). + +%%---------------------------------------------------------------------- +%% External exports +%%---------------------------------------------------------------------- +%% Mandatory server functions +-export([init/1, + terminate/2, + code_change/3]). + +-export([reset/1, + next_one/1, + next_n/2, + destroy/1]). + +%%---------------------------------------------------------------------- +%% Internal exports +%%---------------------------------------------------------------------- +-export([ + ]). + +%%---------------------------------------------------------------------- +%% Records +%%---------------------------------------------------------------------- +-record(state, {properties, counter=1, length}). + +%%---------------------------------------------------------------------- +%% Macros +%%---------------------------------------------------------------------- +-define(CreateInitState(L), #state{properties = L, length = length(L)}). +-define(get_Properties(S), S#state.properties). +-define(get_Counter(S), S#state.counter). +-define(get_Length(S), S#state.length). + +-define(set_Properties(S, P), S#state{properties = P}). +-define(set_Counter(S, C), S#state{counter = C}). +-define(set_Length(S, L), S#state{length = L}). + +-define(increment_Counter(S), S#state{counter = S#state.counter+1}). +-define(decrement_Counter(S), S#state{counter = S#state.counter-1}). +-define(addto_Counter(S, N), S#state{counter = S#state.counter+N}). +-define(subfrom_Counter(S, N), S#state{counter = S#state.counter-N}). + + +%%====================================================================== +%% External functions +%%====================================================================== +%%---------------------------------------------------------------------- +%% Function : init/1 +%% Description: Initiates the server +%% Returns : {ok, State} | +%% {ok, State, Timeout} | +%% ignore | +%% {stop, Reason} +%%---------------------------------------------------------------------- +init(Properties) -> + {ok, ?CreateInitState(Properties)}. + +%%---------------------------------------------------------------------- +%% Function : terminate/2 +%% Description: Shutdown the server +%% Returns : any (ignored by gen_server) +%%---------------------------------------------------------------------- +terminate(_Reason, _State) -> + ok. + +%%---------------------------------------------------------------------- +%% Function : code_change/3 +%% Description: Convert process state when code is changed +%% Returns : {ok, NewState} +%%---------------------------------------------------------------------- +code_change(_OldVsn, State, _Extra) -> + {ok, State}. + +%%---------------------------------------------------------------------% +%% Function : reset +%% Arguments : - +%% Description: +%% Returns : {ok, NewState} +%%---------------------------------------------------------------------- +reset(State) -> + {reply, ok, ?set_Counter(State, 1)}. + +%%---------------------------------------------------------------------% +%% Function : next_one +%% Arguments : - +%% Description: +%% Returns : {ok, {bool(), PropertyName}, NewState} +%%---------------------------------------------------------------------- +next_one(State) when ?get_Counter(State) > ?get_Length(State) -> + {reply, {false, ""}, State}; +next_one(State) -> + {reply, {true, lists:nth(?get_Counter(State), ?get_Properties(State))}, + ?set_Counter(State, 1+?get_Counter(State))}. + +%%---------------------------------------------------------------------% +%% Function : next_n +%% Arguments : N - how many properties we should return. +%% Description: +%% Returns : {ok, {bool(), PropertyNameList}, NewState} +%%---------------------------------------------------------------------- +next_n(State, N) -> + case lists:sublist(?get_Properties(State), ?get_Counter(State), N) of + Properties when N+?get_Counter(State) < ?get_Length(State) -> + {reply, {true, Properties}, ?set_Counter(State, N+?get_Counter(State))}; + Properties -> + {reply, {false, Properties}, ?set_Counter(State, ?get_Length(State))} + end. + +%%---------------------------------------------------------------------% +%% Function : destroy +%% Arguments : - +%% Description: Terminate the object +%% Returns : {ok, NewState} +%%---------------------------------------------------------------------- +destroy(State) -> + {stop, normal, ok, State}. + +%%====================================================================== +%% Internal functions +%%====================================================================== + +%%====================================================================== +%% END OF MODULE +%%====================================================================== diff --git a/lib/cosProperty/src/CosPropertyService_PropertySetDefFactory_impl.erl b/lib/cosProperty/src/CosPropertyService_PropertySetDefFactory_impl.erl new file mode 100644 index 0000000000..b099026b88 --- /dev/null +++ b/lib/cosProperty/src/CosPropertyService_PropertySetDefFactory_impl.erl @@ -0,0 +1,179 @@ +%%---------------------------------------------------------------------- +%% +%% %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_PropertySetDefFactory_impl.erl +%% Description : +%% +%%---------------------------------------------------------------------- +-module('CosPropertyService_PropertySetDefFactory_impl'). + +%%---------------------------------------------------------------------- +%% Include files +%%---------------------------------------------------------------------- +-include_lib("orber/include/corba.hrl"). +-include_lib("orber/src/orber_iiop.hrl"). +-include("CosPropertyService.hrl"). +-include("cosProperty.hrl"). + +%%---------------------------------------------------------------------- +%% External exports +%%---------------------------------------------------------------------- +-export([init/1, + terminate/2, + code_change/3]). + +-export([create_propertysetdef/2, + create_constrained_propertysetdef/4, + create_initial_propertysetdef/3]). + +%%---------------------------------------------------------------------- +%% Internal exports +%%---------------------------------------------------------------------- +-export([]). + +%%---------------------------------------------------------------------- +%% Records +%%---------------------------------------------------------------------- +-record(state, {}). + +%%---------------------------------------------------------------------- +%% Macros +%%---------------------------------------------------------------------- +-define(checkTCfun, fun(TC) -> orber_tc:check_tc(TC) end). + +%%====================================================================== +%% External functions +%%====================================================================== +%%---------------------------------------------------------------------- +%% Function : init/1 +%% Returns : {ok, State} | +%% {ok, State, Timeout} | +%% ignore | +%% {stop, Reason} +%% Description: Initiates the server +%%---------------------------------------------------------------------- +init([]) -> + {ok, #state{}}. + +%%---------------------------------------------------------------------- +%% Function : terminate/2 +%% Returns : any (ignored by gen_server) +%% Description: Shutdown the server +%%---------------------------------------------------------------------- +terminate(_Reason, _State) -> + ok. + +%%---------------------------------------------------------------------- +%% Function : code_change/3 +%% Returns : {ok, NewState} +%% Description: Convert process state when code is changed +%%---------------------------------------------------------------------- +code_change(_OldVsn, State, _Extra) -> + {ok, State}. + +%%---------------------------------------------------------------------% +%% Function : create_propertysetdef +%% Arguments : +%% Returns : CosPropertyService::PropertySetDef reference. +%% Description: +%%---------------------------------------------------------------------- +create_propertysetdef(_OE_This, State) -> + {reply, + 'CosPropertyService_PropertySetDef': + oe_create({normal, [], [], [], ?PropertySetDef}, [{pseudo, true}]), + State}. + +%%---------------------------------------------------------------------% +%% Function : create_constrained_propertysetdef +%% Arguments : PropTypes - list of property types. +%% PropDefs - list of property defs. +%% Returns : CosPropertyService::PropertySetDef | +%% {'EXCEPTION', CosPropertyService::ConstraintNotSupported} +%% Description: +%%---------------------------------------------------------------------- +create_constrained_propertysetdef(_OE_This, State, PropTypes, PropDefs) -> + case lists:all(?checkTCfun, PropTypes) of + true -> + crosscheckTC(PropDefs, PropTypes), + {reply, + 'CosPropertyService_PropertySetDef': + oe_create({normal, PropTypes, PropDefs, [], ?PropertySetDef}, [{pseudo, true}]), + State}; + false -> + corba:raise(#'CosPropertyService_ConstraintNotSupported'{}) + end. + +crosscheckTC([], _) -> + ok; +crosscheckTC([#'CosPropertyService_PropertyDef' + {property_name = Name, + property_value = Value, + property_mode = _Mode}|T], TCs) -> + case lists:member(any:get_typecode(Value), TCs) of + true when Name =/= "" -> + crosscheckTC(T, TCs); + _ -> + corba:raise(#'CosPropertyService_ConstraintNotSupported'{}) + end. + +%%---------------------------------------------------------------------% +%% Function : create_initial_propertysetdef +%% Arguments : +%% Returns : CosPropertyService::PropertySetDef | +%% {'EXCEPTION', CosPropertyService::MultipleExceptions} +%% Description: +%%---------------------------------------------------------------------- +create_initial_propertysetdef(_OE_This, State, PropDefs) -> + InitProps = evaluate_propertysetdef(PropDefs), + {reply, + 'CosPropertyService_PropertySetDef': + oe_create({normal, [], [], InitProps, ?PropertySetDef}, [{pseudo, true}]), + State}. + +%%====================================================================== +%% Internal functions +%%====================================================================== +evaluate_propertysetdef(SetDefs) -> + evaluate_propertysetdef(SetDefs, [], []). +evaluate_propertysetdef([], NewProperties, []) -> + %% No exceptions found. + NewProperties; +evaluate_propertysetdef([], _, Exc) -> + corba:raise(#'CosPropertyService_MultipleExceptions'{exceptions = Exc}); +evaluate_propertysetdef([#'CosPropertyService_PropertyDef' + {property_name = Name, + property_value = Value, + property_mode = Mode}|T], X, Exc) -> + case orber_tc:check_tc(any:get_typecode(Value)) of + true -> + evaluate_propertysetdef(T, [{Name, Value, Mode}|X], Exc); + false -> + evaluate_propertysetdef(T, X, [#'CosPropertyService_PropertyException' + {reason = unsupported_type_code, + failing_property_name = Name}|Exc]) + end. + + + +%%====================================================================== +%% END OF MODULE +%%====================================================================== + 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 ----------------------------- diff --git a/lib/cosProperty/src/CosPropertyService_PropertySetFactory_impl.erl b/lib/cosProperty/src/CosPropertyService_PropertySetFactory_impl.erl new file mode 100644 index 0000000000..ad3cdb62d4 --- /dev/null +++ b/lib/cosProperty/src/CosPropertyService_PropertySetFactory_impl.erl @@ -0,0 +1,176 @@ +%%---------------------------------------------------------------------- +%% +%% %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_PropertySetFactory_impl.erl +%% Description : +%% +%%---------------------------------------------------------------------- +-module('CosPropertyService_PropertySetFactory_impl'). + +%%---------------------------------------------------------------------- +%% Include files +%%---------------------------------------------------------------------- +-include_lib("orber/include/corba.hrl"). +-include_lib("orber/src/orber_iiop.hrl"). +-include("CosPropertyService.hrl"). +-include("cosProperty.hrl"). + +%%---------------------------------------------------------------------- +%% External exports +%%---------------------------------------------------------------------- +-export([init/1, + terminate/2, + code_change/3]). + +-export([create_propertyset/2, + create_constrained_propertyset/4, + create_initial_propertyset/3]). + + +%%---------------------------------------------------------------------- +%% Internal exports +%%---------------------------------------------------------------------- +-export([]). + +%%---------------------------------------------------------------------- +%% Records +%%---------------------------------------------------------------------- +-record(state, {}). + +%%---------------------------------------------------------------------- +%% Macros +%%---------------------------------------------------------------------- +-define(checkTCfun, fun(TC) -> orber_tc:check_tc(TC) end). + +%%====================================================================== +%% External functions +%%====================================================================== +%%---------------------------------------------------------------------- +%% Function : init/1 +%% Returns : {ok, State} | +%% {ok, State, Timeout} | +%% ignore | +%% {stop, Reason} +%% Description: Initiates the server +%%---------------------------------------------------------------------- +init([]) -> + {ok, #state{}}. + +%%---------------------------------------------------------------------- +%% Function : terminate/2 +%% Returns : any (ignored by gen_server) +%% Description: Shutdown the server +%%---------------------------------------------------------------------- +terminate(_Reason, _State) -> + ok. + +%%---------------------------------------------------------------------- +%% Function : code_change/3 +%% Returns : {ok, NewState} +%% Description: Convert process state when code is changed +%%---------------------------------------------------------------------- +code_change(_OldVsn, State, _Extra) -> + {ok, State}. + +%%---------------------------------------------------------------------- +%% Function : create_propertyset +%% Arguments : +%% Returns : CosPropertyService::PropertySet reference. +%% Description: +%%---------------------------------------------------------------------- +create_propertyset(_OE_This, State) -> + {reply, + 'CosPropertyService_PropertySetDef': + oe_create({normal, [], [], [], ?PropertySet}, [{pseudo, true}]), + State}. + +%%---------------------------------------------------------------------- +%% Function : create_constrained_propertyset +%% Arguments : PropTypes - list of property types. +%% Properties - list of properties. +%% Returns : CosPropertyService::PropertySet | +%% {'EXCEPTION', CosPropertyService::ConstraintNotSupported} +%% Description: +%%---------------------------------------------------------------------- +create_constrained_propertyset(_OE_This, State, PropTypes, Properties) -> + case lists:all(?checkTCfun, PropTypes) of + true -> + crosscheckTC(Properties, PropTypes), + {reply, + 'CosPropertyService_PropertySetDef': + oe_create({normal, PropTypes, Properties, [], ?PropertySet}, + [{pseudo, true}]), + State}; + false -> + corba:raise(#'CosPropertyService_ConstraintNotSupported'{}) + end. + +crosscheckTC([], _) -> + ok; +crosscheckTC([#'CosPropertyService_Property' + {property_name = Name, + property_value = Value}|T], TCs) -> + case lists:member(any:get_typecode(Value), TCs) of + true when Name =/= "" -> + crosscheckTC(T, TCs); + _ -> + corba:raise(#'CosPropertyService_ConstraintNotSupported'{}) + end. + +%%---------------------------------------------------------------------- +%% Function : create_initial_propertyset +%% Arguments : Properties - list of properties. +%% Returns : CosPropertyService::PropertySetDef | +%% {'EXCEPTION', CosPropertyService::MultipleExceptions} +%% Description: +%%---------------------------------------------------------------------- +create_initial_propertyset(_OE_This, State, Properties) -> + InitProps = evaluate_propertyset(Properties), + {reply, + 'CosPropertyService_PropertySetDef': + oe_create({normal, [], [], InitProps, ?PropertySet}, [{pseudo, true}]), + State}. + +%%====================================================================== +%% Internal functions +%%====================================================================== +evaluate_propertyset(Sets) -> + evaluate_propertyset(Sets, [], []). +evaluate_propertyset([], NewProperties, []) -> + %% No exceptions found. + NewProperties; +evaluate_propertyset([], _, Exc) -> + corba:raise(#'CosPropertyService_MultipleExceptions'{exceptions = Exc}); +evaluate_propertyset([#'CosPropertyService_Property' + {property_name = Name, + property_value = Value}|T], X, Exc) -> + case orber_tc:check_tc(any:get_typecode(Value)) of + true -> + evaluate_propertyset(T, [{Name, Value, normal}|X], Exc); + false -> + evaluate_propertyset(T, X, [#'CosPropertyService_PropertyException' + {reason = unsupported_type_code, + failing_property_name = Name}|Exc]) + end. + +%%====================================================================== +%% END OF MODULE +%%====================================================================== diff --git a/lib/cosProperty/src/Makefile b/lib/cosProperty/src/Makefile new file mode 100644 index 0000000000..1d2119dfb3 --- /dev/null +++ b/lib/cosProperty/src/Makefile @@ -0,0 +1,183 @@ +# +# %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% +# +# +include $(ERL_TOP)/make/target.mk + +ifeq ($(TYPE),debug) +ERL_COMPILE_FLAGS += -Ddebug -W +endif + +include $(ERL_TOP)/make/$(TARGET)/otp.mk + +# ---------------------------------------------------- +# Application version +# ---------------------------------------------------- +include ../vsn.mk +VSN=$(COSPROPERTY_VSN) + +# ---------------------------------------------------- +# Release directory specification +# ---------------------------------------------------- +RELSYSDIR = $(RELEASE_PATH)/lib/cosProperty-$(VSN) + +EXTERNAL_INC_PATH = ../include + +# ---------------------------------------------------- +# Target Specs +# ---------------------------------------------------- + +MODULES = \ + cosProperty \ + CosPropertyService_PropertySetDefFactory_impl \ + CosPropertyService_PropertySetDef_impl \ + CosPropertyService_PropertySetFactory_impl \ + CosPropertyService_PropertiesIterator_impl \ + CosPropertyService_PropertyNamesIterator_impl + + +ERL_FILES = $(MODULES:%=%.erl) +HRL_FILES = \ + cosProperty.hrl \ + +GEN_ERL_FILES = \ + oe_CosProperty.erl \ + CosPropertyService_ConflictingProperty.erl \ + CosPropertyService_ConstraintNotSupported.erl \ + CosPropertyService_FixedProperty.erl \ + CosPropertyService_InvalidPropertyName.erl \ + CosPropertyService_MultipleExceptions.erl \ + CosPropertyService_Properties.erl \ + CosPropertyService_PropertiesIterator.erl \ + CosPropertyService_Property.erl \ + CosPropertyService_PropertyDef.erl \ + CosPropertyService_PropertyDefs.erl \ + CosPropertyService_PropertyException.erl \ + CosPropertyService_PropertyExceptions.erl \ + CosPropertyService_PropertyMode.erl \ + CosPropertyService_PropertyModes.erl \ + CosPropertyService_PropertyNames.erl \ + CosPropertyService_PropertyNamesIterator.erl \ + CosPropertyService_PropertyNotFound.erl \ + CosPropertyService_PropertySet.erl \ + CosPropertyService_PropertySetDef.erl \ + CosPropertyService_PropertySetDefFactory.erl \ + CosPropertyService_PropertySetFactory.erl \ + CosPropertyService_PropertyTypes.erl \ + CosPropertyService_ReadOnlyProperty.erl \ + CosPropertyService_UnsupportedMode.erl \ + CosPropertyService_UnsupportedProperty.erl \ + CosPropertyService_UnsupportedTypeCode.erl + +LOCAL_HRL_FILES = \ + oe_CosProperty.hrl \ + CosPropertyService.hrl \ + CosPropertyService_PropertiesIterator.hrl \ + CosPropertyService_PropertyNamesIterator.hrl \ + CosPropertyService_PropertySet.hrl \ + CosPropertyService_PropertySetDef.hrl \ + CosPropertyService_PropertySetDefFactory.hrl \ + CosPropertyService_PropertySetFactory.hrl + +GEN_HRL_FILES = $(LOCAL_HRL_FILES:%=$(EXTERNAL_INC_PATH)/%) + +GEN_FILES = \ + $(GEN_HRL_FILES) \ + $(GEN_ERL_FILES) + +TARGET_FILES = \ + $(GEN_ERL_FILES:%.erl=$(EBIN)/%.$(EMULATOR)) \ + $(MODULES:%=$(EBIN)/%.$(EMULATOR)) + +IDL_FILES = \ + CosProperty.idl + +APPUP_FILE = cosProperty.appup +APPUP_SRC = $(APPUP_FILE).src +APPUP_TARGET = $(EBIN)/$(APPUP_FILE) + +APP_FILE = cosProperty.app +APP_SRC = $(APP_FILE).src +APP_TARGET = $(EBIN)/$(APP_FILE) + +# ---------------------------------------------------- +# FLAGS +# ---------------------------------------------------- +ERL_IDL_FLAGS += -pa $(ERL_TOP)/lib/cosProperty/ebin \ + -pa $(ERL_TOP)/lib/ic/ebin\ + -pa $(ERL_TOP)/lib/orber/ebin + +# The -pa option is just used temporary until erlc can handle +# includes from other directories than ../include . +ERL_COMPILE_FLAGS += \ + $(ERL_IDL_FLAGS) \ + -pa $(ERL_TOP)/lib/orber/include \ + -pa $(ERL_TOP)/lib/cosProperty/include \ + -I$(ERL_TOP)/lib/cosProperty/include \ + -I$(ERL_TOP)/lib/orber/include \ + +'{parse_transform,sys_pre_attributes}' \ + +'{attribute,insert,app_vsn,"cosProperty_$(COSPROPERTY_VSN)"}' + + +# ---------------------------------------------------- +# Targets +# ---------------------------------------------------- +opt: $(TARGET_FILES) $(APP_TARGET) $(APPUP_TARGET) + +debug: + @${MAKE} TYPE=debug opt + +cleanb: + rm -f $(TARGET_FILES) $(APP_TARGET) $(APPUP_TARGET) + rm -f errs core *~ + +clean: + rm -f $(TARGET_FILES) $(GEN_FILES) $(APP_TARGET) $(APPUP_TARGET) + rm -f errs core *~ + +$(APP_TARGET): $(APP_SRC) + sed -e 's;%VSN%;$(VSN);' $< > $@ + +$(APPUP_TARGET): $(APPUP_SRC) ../vsn.mk + sed -e 's;%VSN%;$(VSN);' $< > $@ + +docs: + +# ---------------------------------------------------- +# Special Build Targets +# ---------------------------------------------------- +$(GEN_ERL_FILES) $(GEN_HRL_FILES): CosProperty.idl + erlc $(ERL_IDL_FLAGS) +'{cfgfile,"CosProperty.cfg"}' CosProperty.idl + mv $(LOCAL_HRL_FILES) $(EXTERNAL_INC_PATH) + + +# ---------------------------------------------------- +# Release Target +# ---------------------------------------------------- +include $(ERL_TOP)/make/otp_release_targets.mk + +release_spec: opt + $(INSTALL_DIR) $(RELSYSDIR)/ebin + $(INSTALL_DATA) $(TARGET_FILES) $(APP_TARGET) $(APPUP_TARGET) $(RELSYSDIR)/ebin + $(INSTALL_DIR) $(RELSYSDIR)/src + $(INSTALL_DATA) $(GEN_FILES) $(IDL_FILES) $(RELSYSDIR)/src + $(INSTALL_DATA) $(ERL_FILES) $(HRL_FILES) $(GEN_ERL_FILES) $(IDL_FILES) $(RELSYSDIR)/src + $(INSTALL_DIR) $(RELSYSDIR)/include + $(INSTALL_DATA) $(GEN_HRL_FILES) $(RELSYSDIR)/include + +release_docs_spec: diff --git a/lib/cosProperty/src/cosProperty.app.src b/lib/cosProperty/src/cosProperty.app.src new file mode 100644 index 0000000000..3099e904f7 --- /dev/null +++ b/lib/cosProperty/src/cosProperty.app.src @@ -0,0 +1,45 @@ +{application, cosProperty, + [{description, "The Erlang CosProperty application"}, + {vsn, "%VSN%"}, + {modules, + [ + 'cosProperty', + 'CosPropertyService_PropertySetDefFactory_impl', + 'CosPropertyService_PropertySetDef_impl', + 'CosPropertyService_PropertySetFactory_impl', + 'CosPropertyService_PropertiesIterator_impl', + 'CosPropertyService_PropertyNamesIterator_impl', + 'oe_CosProperty', + 'CosPropertyService_ConflictingProperty', + 'CosPropertyService_ConstraintNotSupported', + 'CosPropertyService_FixedProperty', + 'CosPropertyService_InvalidPropertyName', + 'CosPropertyService_MultipleExceptions', + 'CosPropertyService_Properties', + 'CosPropertyService_PropertiesIterator', + 'CosPropertyService_Property', + 'CosPropertyService_PropertyDef', + 'CosPropertyService_PropertyDefs', + 'CosPropertyService_PropertyException', + 'CosPropertyService_PropertyExceptions', + 'CosPropertyService_PropertyMode', + 'CosPropertyService_PropertyModes', + 'CosPropertyService_PropertyNames', + 'CosPropertyService_PropertyNamesIterator', + 'CosPropertyService_PropertyNotFound', + 'CosPropertyService_PropertySet', + 'CosPropertyService_PropertySetDef', + 'CosPropertyService_PropertySetDefFactory', + 'CosPropertyService_PropertySetFactory', + 'CosPropertyService_PropertyTypes', + 'CosPropertyService_ReadOnlyProperty', + 'CosPropertyService_UnsupportedMode', + 'CosPropertyService_UnsupportedProperty', + 'CosPropertyService_UnsupportedTypeCode' + ] + }, + {registered, [oe_cosPropertySup]}, + {applications, [orber, stdlib, kernel]}, + {env, []}, + {mod, {cosProperty, []}} +]}. diff --git a/lib/cosProperty/src/cosProperty.appup.src b/lib/cosProperty/src/cosProperty.appup.src new file mode 100644 index 0000000000..f3eead4a0c --- /dev/null +++ b/lib/cosProperty/src/cosProperty.appup.src @@ -0,0 +1,6 @@ +{"%VSN%", + [ + ], + [ + ] +}. diff --git a/lib/cosProperty/src/cosProperty.erl b/lib/cosProperty/src/cosProperty.erl new file mode 100644 index 0000000000..2368ee3db6 --- /dev/null +++ b/lib/cosProperty/src/cosProperty.erl @@ -0,0 +1,414 @@ +%%-------------------------------------------------------------------- +%% +%% %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 : cosProperty.erl +%% Purpose : +%%---------------------------------------------------------------------- + +-module(cosProperty). + +%%--------------- INCLUDES ----------------------------------- +-include("cosProperty.hrl"). +-include_lib("cosProperty/include/CosPropertyService.hrl"). + +%%--------------- EXPORTS------------------------------------- +%% cosProperty API external +-export([start/0, + start_SetDefFactory/0, + start_SetFactory/0, + stop_SetDefFactory/1, + stop_SetFactory/1, + stop/0, + install/0, + install/1, + install_db/0, + install_db/1, + install_db/2, + uninstall/0, + uninstall/1, + uninstall_db/0]). + +%% cosProperty API internal +-export([create_link/3, + get_option/3, + type_check/2, + query_result/1, + start_PropertiesIterator/1, + start_PropertyNamesIterator/1, + create_static_SetDef/2]). + +%% Application callbacks +-export([start/2, init/1, stop/1]). + +%%--------------- DEFINES ------------------------------------ + +-define(SUPERVISOR_NAME, oe_cosPropertySup). +-define(SUP_FLAG, {simple_one_for_one,50,10}). +-define(SUP_PROP_SPEC(T,I), + ['CosPropertyService_PropertiesIterator',I, + [{sup_child, true}, {regname, {global, T}}]]). +-define(SUP_NAMES_SPEC(T,I), + ['CosPropertyService_PropertyNamesIterator',I, + [{sup_child, true}, {regname, {global, T}}]]). +-define(SUP_CHILD, + {"oe_PropertyChild", + {cosProperty,create_link, []}, + transient,100000,worker, + []}). + +%%------------------------------------------------------------ +%% function : install +%% Arguments: - +%% Returns : ok | EXIT | EXCEPTION +%% Effect : Install necessary data in the IFR DB +%%------------------------------------------------------------ +install() -> + install([]). +install(_Options) -> + case catch oe_CosProperty:'oe_register'() of + ok -> + ok; + {'EXIT',{unregistered,App}} -> + ?write_ErrorMsg("Unable to register cosProperty; application ~p not registered.~n", + [App]), + exit({unregistered,App}); + {'EXCEPTION',_} -> + ?write_ErrorMsg("Unable to register cosProperty; propably already registered. +You are adviced to confirm this.~n", []), + exit({error, "Register in the IFR failed."}); + Reason -> + ?write_ErrorMsg("Unable to register cosProperty; reason ~p", [Reason]), + exit({error, "Register in the IFR failed."}) + end. + +%%------------------------------------------------------------ +%% function : install_db +%% Arguments: - +%% Returns : ok | EXIT | EXCEPTION +%% Effect : Install necessary data in the IFR DB +%%------------------------------------------------------------ +install_db() -> + install_db(infinity, []). +install_db(Timeout) -> + install_db(Timeout, []). +install_db(Timeout, Options) -> + case install_table(Timeout, Options) of + ok -> + ok; + {error, [DB_tables_created, Wait]} -> + ?write_ErrorMsg("Able to register cosProperty but failed adding table in mnesia (~p, ~p)", + [DB_tables_created, Wait]), + exit({error, "Adding data in mnesia failed."}); + Why -> + ?write_ErrorMsg("Able to register cosProperty but failed adding table in mnesia with reason ~p", + [Why]), + exit({error, "Adding data in mnesia failed."}) + end. + +%%------------------------------------------------------------ +%% function : install_table +%% Arguments: - +%% Returns : ok | {error, Data} +%% Effect : Install necessary data in mnesia +%%------------------------------------------------------------ +install_table(Timeout, Options) -> + %% Fetch a list of the defined tables to see if 'oe_CosPropertyService' + %% is defined. + AllTabs = mnesia:system_info(tables), + DB_tables_created = + case lists:member('oe_CosPropertyService', AllTabs) of + true -> + case lists:member({local_content, true}, + Options) of + true-> + mnesia:add_table_copy('oe_CosPropertyService', + node(), + ram_copies); + _-> + mnesia:create_table('oe_CosPropertyService',[{attributes, + record_info(fields, + 'oe_CosPropertyService')} + |Options]) + end; + _ -> + mnesia:create_table('oe_CosPropertyService',[{attributes, + record_info(fields, + 'oe_CosPropertyService')} + |Options]) + end, + Wait = mnesia:wait_for_tables(['oe_CosPropertyService'], Timeout), + %% Check if any error has occured yet. If there are errors, return them. + if + DB_tables_created == {atomic, ok}, + Wait == ok -> + ok; + true -> + {error, [DB_tables_created, Wait]} + end. + + +%%------------------------------------------------------------ +%% function : query_result +%% Arguments: - +%% Returns : error | Data +%% Effect : Check a read transaction +%%------------------------------------------------------------ +query_result(Qres) -> + case Qres of + {atomic, [Hres]} -> + Hres#oe_CosPropertyService.properties; + {atomic, [_Hres | _Tres]} -> + error; + {atomic, []} -> + error; + _Other -> + error + end. + +%%------------------------------------------------------------ +%% function : uninstall +%% Arguments: - +%% Returns : ok | EXIT | EXCEPTION +%% Effect : Remove data related to cosProperty from the IFR DB +%%------------------------------------------------------------ +uninstall() -> + uninstall([]). +uninstall(_Options) -> + application:stop(cosProperty), + oe_CosProperty:oe_unregister(). + +%%------------------------------------------------------------ +%% function : uninstall +%% Arguments: - +%% Returns : ok | EXIT | EXCEPTION +%% Effect : Remove data related to cosProperty from the IFR DB +%%------------------------------------------------------------ +uninstall_db() -> + application:stop(cosProperty), + case mnesia:delete_table('oe_CosPropertyService') of + {atomic, ok} -> + ok; + {aborted, _Reason} -> + exit({error, "Removing data from mnesia failed."}) + end. + +%%------------------------------------------------------------ +%% function : create_static_SetDef +%% Arguments: +%% Returns : +%% Effect : Starts or stops the cosProperty application. +%%------------------------------------------------------------ +create_static_SetDef(PropTypes, PropDefs) -> + InitProps = propertyDef2local(PropDefs, []), + 'CosPropertyService_PropertySetDef':oe_create({static, fixed_readonly, PropTypes, + PropDefs, InitProps, + ?PropertySetDef}, + [{pseudo, true}]). +propertyDef2local([#'CosPropertyService_PropertyDef' + {property_name = Name, + property_value = Value, + property_mode = fixed_readonly}|T], Acc) -> + propertyDef2local(T, [{Name, Value, fixed_readonly}|Acc]); +propertyDef2local([], Acc) -> + Acc; +propertyDef2local(_, _) -> + exit({error, "Bad Mode type supplied. Must be fixed_readonly"}). + +%%------------------------------------------------------------ +%% function : start/stop +%% Arguments: +%% Returns : +%% Effect : Starts or stops the cosProperty application. +%%------------------------------------------------------------ +start() -> + application:start(cosProperty). +stop() -> + application:stop(cosProperty). + + + +%%-----------------------------------------------------------% +%% function : start_SetDefFactory +%% Arguments: - +%% Returns : A PropertySetDefFactory reference. +%% Effect : +%%------------------------------------------------------------ +start_SetDefFactory() -> + 'CosPropertyService_PropertySetDefFactory':oe_create([], [{pseudo, true}]). + +%%-----------------------------------------------------------% +%% function : start_SetFactory +%% Arguments: - +%% Returns : A PropertySetFactory reference. +%% Effect : +%%------------------------------------------------------------ +start_SetFactory() -> + 'CosPropertyService_PropertySetFactory':oe_create([], [{pseudo, true}]). + +%%-----------------------------------------------------------% +%% function : stop_SetDefFactory +%% Arguments: Factory - A PropertySetDefFactory reference. +%% Returns : +%% Effect : +%%------------------------------------------------------------ +stop_SetDefFactory(Factory) -> + corba:dispose(Factory). + +%%-----------------------------------------------------------% +%% function : stop_SetFactory +%% Arguments: Factory - A PropertySetFactory reference. +%% Returns : +%% Effect : +%%------------------------------------------------------------ +stop_SetFactory(Factory) -> + corba:dispose(Factory). + +%%------------------------------------------------------------ +%% function : start +%% Arguments: Type - see module application +%% Arg - see module application +%% Returns : +%% Effect : Module callback for application +%%------------------------------------------------------------ +start(_, _) -> + supervisor:start_link({local, ?SUPERVISOR_NAME}, cosProperty, app_init). + + +%%------------------------------------------------------------ +%% function : stop +%% Arguments: Arg - see module application +%% Returns : +%% Effect : Module callback for application +%%------------------------------------------------------------ +stop(_) -> + ok. + +%%-----------------------------------------------------------% +%% 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 : start_PropertiesIterator +%% Arguments: +%% Returns : +%% Exception: +%% Effect : +%%------------------------------------------------------------ +start_PropertiesIterator(Args) -> + Name = create_name(propertiesIterator), + case supervisor:start_child(?SUPERVISOR_NAME, ?SUP_PROP_SPEC(Name, Args)) of + {ok, Pid, Obj} when is_pid(Pid) -> + Obj; + _Other-> + corba:raise(#'INTERNAL'{completion_status=?COMPLETED_NO}) + end. + +%%-----------------------------------------------------------% +%% function : start_PropertyNamesIterator +%% Arguments: +%% Returns : +%% Exception: +%% Effect : +%%------------------------------------------------------------ +start_PropertyNamesIterator(Args) -> + Name = create_name(propertiesIterator), + case supervisor:start_child(?SUPERVISOR_NAME, ?SUP_NAMES_SPEC(Name, Args)) of + {ok, Pid, Obj} when is_pid(Pid) -> + Obj; + _Other-> + corba:raise(#'INTERNAL'{completion_status=?COMPLETED_NO}) + end. + + +%%-----------------------------------------------------------% +%% function : get_option +%% Arguments: +%% Returns : +%% Exception: +%% Effect : +%%------------------------------------------------------------ +get_option(Key, OptionList, DefaultList) -> + case lists:keysearch(Key, 1, OptionList) of + {value,{Key,Value}} -> + Value; + _ -> + case lists:keysearch(Key, 1, DefaultList) 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) -> + case catch corba_object:is_a(Obj,Mod:typeID()) of + true -> + ok; + _ -> + corba:raise(#'BAD_PARAM'{completion_status=?COMPLETED_NO}) + end. + + +%%-----------------------------------------------------------% +%% function : create_name/1 +%% Arguments: +%% Returns : +%% Exception: +%% Effect : +%%------------------------------------------------------------ +create_name(Type) -> + {MSec, Sec, USec} = erlang:now(), + lists:concat(['oe_',node(),'_',Type,'_',MSec, '_', Sec, '_', USec]). + +%%--------------- END OF MODULE ------------------------------ + + diff --git a/lib/cosProperty/src/cosProperty.hrl b/lib/cosProperty/src/cosProperty.hrl new file mode 100644 index 0000000000..2755b890c8 --- /dev/null +++ b/lib/cosProperty/src/cosProperty.hrl @@ -0,0 +1,81 @@ +%%---------------------------------------------------------------------- +%% +%% %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 : cosProperty.hrl +%% Purpose : +%%---------------------------------------------------------------------- + + +%%--------------- INCLUDES ----------------------------------- +%% External +-include_lib("orber/include/corba.hrl"). +-include_lib("orber/include/ifr_types.hrl"). + +%%----------------------------------------------------------------- +%% Mnesia Table definition record +%%----------------------------------------------------------------- +-record('oe_CosPropertyService', {key, properties}). + +%%----------------------------------------------------------------- +%% Macros +%%----------------------------------------------------------------- +-define(PropertySet, 0). +-define(PropertySetDef, 1). + +%% This macro returns a read fun suitable for evaluation in a transaction +-define(read_function(Objkey), + fun() -> + mnesia:read(Objkey) + end). + +%% This macro returns a write fun suitable for evaluation in a transaction +-define(write_function(R), + fun() -> + mnesia:write(R) + end). + +%% This macro returns a delete fun suitable for evaluation in a transaction +-define(delete_function(R), + fun() -> + mnesia:delete(R) + end). + +-define(query_check(Q_res), {atomic, Q_res}). + + +-define(write_ErrorMsg(Txt, Arg), +error_logger:error_msg("================ CosProperty ==============~n" + Txt + "===========================================~n", + Arg)). + + + +-ifdef(debug). +-define(debug_print(F,A), + io:format("[LINE: ~p MODULE: ~p] "++F,[?LINE, ?MODULE]++A)). +-define(property_TypeCheck(O,M), 'cosProperty':type_check(O,M)). +-else. +-define(debug_print(F,A), ok). +-define(property_TypeCheck(O,I), ok). +-endif. + +%%--------------- END OF MODULE ------------------------------ |