Previous | Table of Contents | Next |
This sub clause specializes the MOF’s general computational semantics (see Clause 8, “The MOF Abstract Mapping?) for the MOF
to IDL mapping.
The IDL mapping defines PrimitiveType instances that can be used to represent CORBA specific data types in a MOF meta-model.
The IDL mapping maps each of these PrimitiveType instances into CORBA IDL data types, but other technology mappings typically
will not map them.
Please note the following:
1. The types in the CorbaIdlTypes package are provided solely to ease migration of “legacy? meta-models and metadata defined in the context of MOF 1.3 and earlier. Use of these types in new meta-models is discouraged as it will make them CORBA specific.
2. Implementations of the IDL mapping shall recognize the CORBA specific PrimitiveType instances based on their qualified names. Multiple PrimitiveType instances with the required qualified name shall be deemed to mean the same thing.
The CorbaIdlTypes package is a MOF package whose name is “CorbaIdlTypes.? It contains the PrimitiveType instances defined
below, and no other instances. The information below defines the value domain (set) for each type, and the syntax for encoding
values for use in the Model::Constant “value? attribute.
CorbaOctet
This primitive data type represents the CORBA IDL ‘octet’ type.
CorbaShort
This primitive data type represents the CORBA IDL ‘short’ type.
CorbaUnsignedShort
This primitive data type represents the CORBA IDL ‘unsigned short’ type.
CorbaUnsignedLong
This primitive data type represents the CORBA IDL ‘unsigned long’ type.
CorbaUnsignedLongLong
This primitive data type represents the CORBA IDL ‘unsigned long long’ type.
CorbaLongDouble
This primitive data type is the set of IEEE extended double precision floating point numbers (see ANSI/IEEE Standard 754-1985).
This is the minimum requirement for the CORBA IDL ‘long double’ type.
value domainconstant value syntax |
|||||
The subset of the rational numbers that correspond to the values representable as IEEE extended | |||||
double precision floating point numbers (96 bit). | |||||
CORBA IDL floating point literal syntax with an optional leading ‘-’ character. |
CorbaString
This primitive data type represents the CORBA IDL ‘string’ type.
value domainconstant value syntax |
|||||
The infinite set of all finite sequences of 8 bit characters (excluding the zero character value). | |||||
A sequence of 8-bit characters. (Note: a Constant’s ‘value’ string for a CorbaString has no | |||||
surrounding quotes and contains no character escape sequences.) |
CorbaChar
This primitive data type represents the CORBA IDL ‘char’ type.
The set of 8 bit characters.
value domain
One 8-bit character. NUL is represented as an empty String. (Note: a Constant’s ‘value’ string for a CorbaChar has no surrounding
quotes and contains no character escape sequences.)
constant value syntax
CorbaWChar
This primitive data type represents the CORBA IDL ‘wchar’ type.
value domainconstant value syntax |
|||||
The set of 16 bit characters. | |||||
One 16-bit character. NUL is represented as an empty String. (Note: a Constant’s ‘value’ string for a | |||||
CorbaWChar has no surrounding quotes and contains no character escape sequences.) |
IDL for the CorbaIdlTypes module
The IDL for the CorbaIdlTypes package is given below. The IDL is produced by applying the IDL Mapping to the package. It would
typically be “#included? by the IDL for meta-models that import the CorbaIdlTypes package.
#pragma prefix "org.omg.mof"
module CorbaIdlTypes {
typedef sequence < octet > OctetBag;
typedef sequence < octet > OctetSet;
typedef sequence < octet > OctetList;
typedef sequence < octet > OctetUList;
typedef sequence < short > ShortBag;
typedef sequence < short > ShortSet;
typedef sequence < short > ShortList;
typedef sequence < short > ShortUList;
typedef sequence < unsigned short > UShortBag;
typedef sequence < unsigned short > UShortSet;
typedef sequence < unsigned short > UShortList;
typedef sequence < unsigned short > UShortUList;
typedef sequence < unsigned long > ULongBag;
typedef sequence < unsigned long > ULongSet;
typedef sequence < unsigned long > ULongList;
typedef sequence < unsigned long > ULongUList;
typedef sequence < unsigned long long > ULongLongBag; typedef sequence < unsigned long long > ULongLongSet;
typedef sequence < unsigned long long > ULongLongList;
typedef sequence < unsigned long long > ULongLongUList;
typedef sequence < long double > ULongDoubleBag;
typedef sequence < long double > ULongDoubleSet;
typedef sequence < long double > ULongDoubleList;
typedef sequence < long double > ULongDoubleUList;
typedef sequence < string > StringBag;
typedef sequence < string > StringSet;
typedef sequence < string > StringList;
typedef sequence < string > StringUList;
typedef sequence < char > CharBag;
typedef sequence < char > CharSet;
typedef sequence < char > CharList;
typedef sequence < char > CharUList;
typedef sequence < wchar > WCharBag;
typedef sequence < wchar > WCharSet;
typedef sequence < wchar > WCharList;
typedef sequence < wchar > WCharUList;
// This interface would be inheritted by any the Package interface for any Package
// that inheritted the CorbaIdlTypes package
interface CorbaIdlTypesPackage : Reflective::RefPackage { };
// This interface is here for completeness only. There is no point in instantiating
// the CorbaIdlTypesPackage interface.
interface CorbaIdlTypesPackageFactory {
CorbaIdlTypesPackage create_corba_idl_types_package() raises (Reflective::MofError); }; };
The following MOF PrimitiveType instances are mapped to CORBA IDL types in the IDL mapping. Other PrimitiveType instances
have no defined mapping.
PrimitiveType instance |
Corresponding IDL type |
||||
PrimitiveTypes::Boolean | boolean | ||||
PrimitiveTypes::Integer | long | ||||
PrimitiveTypes::Long | long long | ||||
PrimitiveTypes::Float | float | ||||
PrimitiveTypes::Double | double | ||||
PrimitiveTypes::String | wstring | ||||
CorbaIdlTypes::CorbaOctet | octet | ||||
CorbaIdlTypes::CorbaShort | short | ||||
CorbaIdlTypes::CorbaUnsignedShort | unsigned short | ||||
CorbaIdlTypes::CorbaUnsignedLong | unsigned long | ||||
CorbaIdlTypes::CorbaUnsignedLongLong | unsigned long long | ||||
CorbaIdlTypes::CorbaLongDouble | long double | ||||
CorbaIdlTypes::CorbaString | string | ||||
CorbaIdlTypes::CorbaChar | char | ||||
CorbaIdlTypes::CorbaWChar | wchar |
NOTE: The MOF to IDL mapping does not define a standard mapping to the following CORBA IDL primitive data types: Principal,
TypeCode, Any.
The MOF constructed data types are mapped to CORBA IDL types, as follows.
DataType subtype |
Corresponding IDL type |
||||
StructureType(name, fields) | struct name { fields};. | ||||
CollectionType(name, type, ...) | typedef sequence < type > name; | ||||
EnumerationType(name, labels) | enum name { labels }; | ||||
AliasType(name, type) | typedef type name; |
NOTE: The MOF to IDL mapping does not define a standard mapping to the following CORBA IDL constructed types: arrays, bounded
sequences, bounded strings, bounded wide strings, fixed types, union types, value types, boxed value types, interface types
or abstract interface types.
© ISO/IEC 2005 - All rights reserved
The IDL mapping defines all MOF Instance types as CORBA object types that are descended from the “RefObject? interface; see
10.2.4, “Reflective::RefAssociation (abstract),? on page 265
. Equality of Instance objects should be implemented as follows:
• Existing Instance objects are equal if and only if the “refMofId? operation defined by 10.2.3, “Reflective::RefObject (abstract),? on page 254 returns the same string for both objects.
• Non-existent Instance objects are deemed to be equal if and only if they have the same object reference; that is, when the “Object::_is_equivalent? operation returns true.
NOTE: An implementation must take care when comparing Instance object values to distinguish between non-existent (i.e., deleted)
Instance objects and objects that may only be temporarily inaccessible. An operation should only raise an exception for a
non-existent Instance object when it cannot be performed. In particular, an operation that replaces or removes defunct links
or Instance values should not complain that the Instance being removed is defunct.
This sub clause defines the IDL mapping’s computational model for meta-object creation and deletion. It also gives definitions
of copy semantics, though these should currently be viewed as indicative rather than normative.
An M1-level Package object for a non-nested M2-level Package is created by invoking the create operation provided by the corresponding
PackageFactory object. This create operation requires the caller to supply the values for all non-derived classifier-scoped
Attributes. If the supplied initial values do not have the correct multiplicity or if they individually or collectively violate
immediate Constraints defined in the metamodel, the create operation should raise an exception.
Instances of the following dependent M1-level objects are automatically created along with each M1-level Package object:
• An M1-level Package object is created for each nested Package within the outermost Package extent.
• An M1-level Package object is created for each clustered Package within the outermost Package extent.
• An M1-level Class Proxy object is created for each Class within the outermost Package extent.
• An M1-level Association object is created for each Association within the outermost Package extent.
The object references for the dependent Package and Class objects provide the “ref? attributes in the respective Package objects.
The objects are initialized so that the outermost_package and enclosing_package operations return the appropriate M1-level
Package objects.
NOTE: If an M2-level Package P2 clusters an existing top-level M2 Package P1, the above rules mean that two kinds of M1level
P1 Package objects can exist. If the user calls create on a P2 Package Factory object, the resulting P2 Package object will
have its own dependent P1 Package object. On the other hand, if the user calls create on a P1 Package Factory, the resulting
P1 Package object will be an outermost Package object. These two kinds of P1 Package objects behave identically, apart from
their respective “refOutermostPackage? and “refOutermostPackage? operations; see 10.2.3, “Reflective::RefObject
(abstract),? on page 254.
When an M1-level Class Proxy object is created, the values of the non-derived classifier-level Attributes are initialized
from the corresponding create operation arguments. The “all_of_type? and “all_of_kind? collections will initially be empty,
since no M1-level Instance objects will have been created in the Class Proxy extent.
NOTE: An implementation may support other mechanisms for creating or recreating outermost M1-level Package objects. Any such
mechanism must also (re-)create and initialize the necessary dependent objects as above.
An outermost M1-level Package object can be destroyed using the “refDelete? operation; see 10.2.3,
“Reflective::RefObject (abstract),? on page 254. The required computational semantics for deleting an outermost Package
object are straightforward. The following things must occur (in an unspecified order):
• The binding between the outermost Package object and its object reference(s) must be revoked.
• The bindings between all dependent Package, Association, and Class Proxy objects and their object references must be revoked.
• All Instance objects within the extent of the outermost Package object must be destroyed as described below.
NOTE: A typical implementation will delete the metadata and reclaim the space used to store it. However, this behavior is
not essential and in some situations it could be undesirable.
Dependent M1-level Package objects, M1-level Association objects and M1-level Class Proxy objects cannot be directly destroyed
by the user. An implementation of the “refDelete? operation for these objects is required to raise an exception when called
by client code. (The operations may be used to implement outermost Package deletion, but this is beyond the scope of this
specification.)
An M1-level Instance object can be created by invoking the appropriate create operation. Suitable create operations are present
on both M1-level Class Proxy objects and M1-level Instance objects, depending on the M2-level Class inheritance graph. A create
operation requires the caller to supply values for all non-derived instance-scoped Attributes for the Instance object. If
any value does not conform to the Attribute’s multiplicity or if they individually or collectively violate any immediate Constraints
on the meta-model, an exception is raised.
An Instance object is created within the extent of a Class Proxy object for the Instance’s M2-level Class. The Class Proxy
can be found as follows:
1. Find the outermost Package extent containing the object on which the create operation was invoked.
2. Within that extent, find the one and only Class Proxy object for the M2 Class whose instance is being created.
If no Class Proxy can be found by the above, the create request violates the Supertype Closure Rule (see 9.3.11, “The
Supertype Closure Rule,? on page 182) and an exception is raised.
Creation of an Instance object will also fail if the corresponding M2-level Class is abstract. Similarly, it will fail if
the M2-level Class is a “singleton? Class and an Instance object for that Class already exists within the Class Proxy’s extent.
In either case, an exception is raised.
When an Instance object is (successfully) created within the extent of a Class Proxy object, it becomes part of a collection
returned by the Class Proxy object’s “all_of_kind? operation. The Instance object remains a member of that collection for
its lifetime (i.e., until it is deleted).
An Instance object will be deleted in the following three situations:
1. When a client invokes the “refDelete? operation on the Instance object; see 10.2.3, “Reflective::RefObject (abstract),? on page 254.
2. When the Package object for the Instance object’s outermost Package extent is deleted (see above), and
3. When the Instance is a component of a “composite? Instance that is deleted. This applies to composites formed by both Associations and Attributes.
When an Instance object is deleted the following things must occur:
• The binding between the Instance object and its object reference(s) must be revoked.
• The Instance object must be removed from its Class Proxy object’s “all_of_type? collection.
• Any Instance objects that are components of the object being deleted must also be deleted.
• Links involving the deleted Instance object should be deleted as per the “Link lifecycle semantics? specification below.
An implementation will typically delete the state of an Instance object that has been deleted, and reclaim any associated
space.
NOTE: When an Instance object is deleted, corresponding object reference values in non-composite Attributes of other objects
become “dangling? references. These dangling references should not be automatically expunged or converted to nil object references,
since doing so potentially destroys information and creates new structural errors. Instead, it is the user’s responsibility
to ensure that dangling references in Attributes are tidied up in the most appropriate way.
Links can be created and deleted in various ways. These include:
• by the user operations on M1-level Association objects; see 9.3.5, “Association Access and Update Semantics for the IDL Mapping,? on page 173,
• by the user operations corresponding to References on M1-level Instance objects; see 9.3.7, “Attribute Access and Update Semantics for the IDL Mapping,? on page 176,
• by the user copying metadata (using some vendor specific API); see 8.12, “Recommended Copy Semantics,? on page 156 ,
• by the user deleting one or other linked Instance objects; see 9.3.4.2, “Instance object lifecycle semantics,? on page 171 , and
• when the server notices that a linked Instance object no longer exists.
A link is created within the extent of an Association object, and becomes part of the collection returned by the Association
object’s “links()? operation. A link remains within the extent in which it was created for the lifetime of the link (i.e.,
until it is deleted). When a link is deleted, it is removed from the “links? collection. Removing a link does not affect the
lifecycle of the linked Instance objects.
According to
8.9.2.2, “Characteristics of M1-level Associations,? on page 151, deletion of an Instance object causes any
links for that object to become meaningless. Ideally, a well-formed M1-level Association instance should not contain such
links. In practice, the immediate removal of meaningless links from an M1-level Association instance cannot always be implemented,
in particular in the case of links that cross outermost Package extent boundaries.
Instead, a meta-object server is required to behave as follows. When an Instance object is deleted:
• all links referring to the Instance object that belong to Association instances within the same outermost Package extent as the Instance object must also be deleted, and
• any links referring to the Instance object that belong to Association instances in another outermost Package extent as the Instance object may also be deleted.
NOTE: The above semantics means that an Association instance can legally contain links that refer to defunct Instance objects
in other extents.
This sub clause describes the computational semantics of the Association object access and update operations defined in the
MOF to IDL Mapping and the Reflective interfaces. With a couple of exceptions, these semantics transform one Well-formed State
(as defined in 8.9.2.1, “A Mathematical Model of Association State,? on page 150) to another. The
exceptions are as follows:
• Deletion of an Instance object in another outermost Package extent may cause an Association instance to contain links that are not members of Valid_Links.
• Deletion of an Instance object can cause an End_Links set to contain fewer links than is required.
M1-level Instance objects are passed as CORBA object reference values in IDL mapped operations. However, since the Association
State model requires that Links connect Instances, it is not legal to pass the CORBA nil object reference value as a parameter
to any operation on an M1-level Association.
NOTE: While the semantics of Associations are described (below) in terms of sets of pairs of M1-level Instance objects, this
should not be read as implying any particular implementation approach.
There are three kinds of link access operations in the M1-level Association interface generated by the IDL mapping:
• The “all_links? operation returns the current Link_Set for an Association object.
• The “<end_name>? operations return a projection of the corresponding End_Links sets.
• The “exists? operation tests for the existence of a given Link in the Link_Set.
These operations are defined to be side-effect free; that is, they do not modify the State of the Association instance.
The operations for adding links to an M1-level Association vary, depending on whether it has an ordered M2-level AssociationEnd:
• For an unordered Association, the “add? operation adds a Link to the Link_Set.
• For an ordered Association, the “add? and “add_before? operations both add a Link between a pair of Instances to the Link_Set. In the “add? case, the new Link is added after existing Links. In the “add_before? case, the new Link is added immediately before the link selected by the “before? argument.
More precisely, assuming that the first AssociationEnd is the ordered one and the new Link connects Instances i and j. The
Before mapping is updated as follows:
• For “add,? all Links that were in End2_Linksj prior to the operation are Before the new Link when it completes.
• For “add_before,? the Before_Link connects the “before? and j Instances. For all Links that were in End2_Linksj and were Before the Before_Link prior to the operation, the pre-existing Link is Before the new Link after the operation. For all other Links that were in End2_Linksj prior to the operation, the new Link is Before the pre-existing Link after the operation.
• In both cases, the ordering of the other End2_Links sets are unchanged.
A number of constraints apply to the link addition operations:
• A new Link can only be added between extant Instances; that is, the new Link must be a member of Valid_Links.
• An operation cannot add a Link that is already a member of the Link_Set.
• An operation cannot add a Link if it would make the number of members of either End1_Linksi or End2_Linksj greater than the respective AssociationEnd’s “upper? bound.
• An operation cannot add a Link that creates a Composition cycle, or that violates the Composition or Reference Closure rules.
There are two “modify? operations for replacing an existing Link in the Link_Set of an M1-level Association. One operation
(in effect) modifies the Instance at the first end of a Link, and the second modifies the Instance at the second end. While
the operation signatures do not vary, the semantics of the “modify? operations depend on whether the M2level Association has
an ordered AssociationEnd.
• In the non-ordered case, a “modify? operation is almost identical to a “remove? operation followed by an “add? operation. The only difference is in the bounds checking; see below.
• In the ordered case, a “modify? operation can differ from an “add? followed by a “remove? in the way that the Before ordering is handled. Specifically, if we assume that the first AssociationEnd is the ordered one, the Before mapping is updated as follows:
• For “modify_<end1_name>(i, j, k)?, the new Link (between k and j) occupies the same position in the Before ordering of End2_Linksj as the Link (between i and j) that it replaces. • For “modify_<end2_name>(i, j, k)?, the new Link (between i and k) becomes the last Link in the Before ordering of End2_Linksk. • In both cases, the ordering of the other End2_Links sets are unchanged.
A number of constraints apply to the link modification operations:
• The Link that is replaced by the “modify? operation must be a member of Link_Set. However, it need not be a member of Valid_Links.
• The replacement Link that is created by a “modify? operation must be a member of Valid_Links.
• The replacement Link cannot already be a member of the Link_Set.
• A “modify? operation cannot remove a Link if doing so would make the number of members of End1_Linksi or End2_Linksj less than the respective AssociationEnd’s “lower? bound. (However, a Link can be produced in this situation.)
• A “modify? operation cannot produce a Link that creates a Composition cycle, or that violates the Composition or Reference Closure rules.
• A “modify? operation cannot produce a Link that would make the number of members in either the End1_Linksk or
End2_Linksk sets greater than the respective AssociationEnd’s “upper? bound.
NOTE: A modify operation of the form “modify_<end1_name>(i, j, i)? is treated as a “no-op.? In particular, it does not trigger
checking of “lower? or “upper? bounds.
The “remove? operation can be used to delete an exist Link (between i and j) from the Link_Set of an M1-level Association.
The constraints that apply to the link removal operation are:
• The operation cannot remove a Link if doing so would make the number of members of End1_Linksi or End2_Linksj less than the respective AssociationEnd’s “lower? bound.
• The operation cannot remove a Link that is not a member of the Link_Set. However, it should succeed if the Link is a member of Link_Set but not of Valid_Links.
The operation descriptions given above assume that the AssociationEnds of the M2-level Association have been defined with
“isChangeable? and “isNavigable? set to true. If this is not so, the main impact is that certain operations are suppressed:
• If an AssociationEnd of an Association is defined as non-changeable (i.e., when its “isChangeable? flag is set to false), the IDL mapping suppresses various link update operations. The “add,? “add_before,? and “remove? operations are suppressed if either AssociationEnd is non-changeable. Furthermore, the “modify_<end_name>? operation is suppressed for any AssociationEnd that is non-changeable, along with any related Reference-based operations.
• If an AssociationEnd of an Association is defined as non-navigable (i.e., when its “isNavigable? flag is set to false) the IDL mapping suppresses any link operations that depend on the ability to search based on that AssociationEnd. Specifically, it suppresses the “<assoc_end>?, “add_before_<end>?, “modify_<end>? operations.
Setting “isDerived? to be true for an M2-level Association is a “hint? that an M1-level Association’s Link_Set and Before
mapping should be computed from other M1-level information. Apart from this, the IDL mapping makes no distinction between
derived and non-derived Associations. Equivalent IDL interfaces are generated in each case, and the semantics are defined
to be equivalent. If a derived Association’s operations are coded by hand, it is the programmer’s responsibility to ensure
that they implement the required semantics.
Some combinations of the Association and AssociationEnd flags result in generated interfaces that are of little use. For
example:
• Setting “isChangeable? to be false on one AssociationEnd and not the other results in an M1-level Association that supports one “modify? operation but no “add? or “remove? operations.
• Setting “isChangeable? to be false on an Association that has “isDerived? set to false results in a “stored? Association with no operations to update the Link_Set.
The IDL mapping maps M2-level Attributes to a variety of operations, depending on the Attribute’s “multiplicity? settings.
There are three major cases:
1. single-valued with bounds of [1..1]),
2. optional with bounds of [0..1], and
3. multi-valued.
Unlike Associations, the CORBA “nil? object reference is a legal (and logically distinct) value for any Class or object reference-valued
Attribute. When an accessor operation returns a “nil? object reference, this does not necessarily mean that the Attribute
has no value(s). In addition, the lifecycle semantics for Attributes in the IDL mapping mean that an accessor operation can
return a reference for a non-existent object.
NOTE: While the semantics of Attributes are described (below) in terms of notional relations between M1-level values, this
should not be read as implying any particular implementation approach.
The interfaces and semantics for single-valued Attributes are the simplest to describe. A single-valued Attribute (i.e., one
whose “lower? and “upper? bounds are set to one) is mapped to these IDL operations:
• “<attr_name>?
• “set_<attr_name>?.
The “<attr_name>? operation returns the current value of the named Attribute for an M1-level Instance object. In the single-valued
case, this is a single Instance of the Attribute’s M1-level base type as mapped by the IDL mapping. In the
terminology of 8.6.1, “Attribute name and type,? on page 142, the operation returns the M1-level value that is related to
the Instance object by the notional “<attr_name>? Class — AttrType relation.
The “set_<attr_name>? operation replaces the current value of the named Attribute for an M1-level Instance with a new value.
As before, the new value is a single Instance of the Attribute’s M1-level base type as mapped by the IDL mapping. The operation
replaces the existing Class — AttrType relationship with a new one between the Instance object and the new value.
The behavior of “set_<attr_name>? for a Class-valued Attribute (i.e., one with “composite? aggregation semantics) is constrained
as follows:
• The new value supplied must be either a reference to an existing Instance object or a nil object reference.
• The new value (i.e., the component Instance) must not already be a component of another Instance object.
• The composite and component Instance objects must belong to the same outermost M1-level Package extent (i.e., the Composition Closure rule must not be violated).
• Creating the new Class — AttrType relationship must not create a composition cycle.
The interfaces and semantics for optional Attributes are also relatively straight-forward. An optional Attribute (i.e., one
whose “lower? bound is 0 and whose “upper? bound is 1) maps to three operations:
1. “<attr_name>?
2. “set_<attr_name>?
3. “unset_<attr_name>?
The IDL mapping treats an M1-level optional Attribute as having two states. In the “set? state, the Attribute has a value
that is an instance of the Attribute’s M1-level base type. In the “unset? state, the Attribute has no value.
In the single-valued case, “<attr_name>? simply returns the current M1-level value for the Attribute. In the optional case,
the semantics depend on whether the Attribute is currently “set? or “unset.?
• If the Attribute is “set? (i.e., there is a Class — AttrType relationship between the Instance object and some other value), the “<attr_name>? operation returns the related value.
• If the Attribute is “unset? (i.e., there is no Class — AttrType relationship with the Instance object in the “class? role), the “<attr_name>? operation raises an exception.
The “set_<attr_name>? operation behaves exactly as in the single-valued case; it replaces the existing Class — AttrType relationship
(if any) with a relationship with the new value. As a consequence, the Attribute enters the “set? state. The structural constraints
for “set_<attr_name>? in the single-valued case apply here as well.
The “unset_<attr_name>? operation removes the Class — AttrType relationship, if it exists, leaving the Attribute in the “unset?
state.
The interfaces and semantics for multi-valued Attributes are relatively complicated, and depend to a considerable extent on
the settings of the “isOrdered? and “isUnique? fields of the M2-level Attribute’s “multiplicity? property.
M1-level operations on multi-valued Attributes can be divided into two groups. The “<attr_name>? and “set_<attr_name>? operations
access and update the Attribute’s state as a single value, transferring it as a CORBA sequence type. The other operations
treat the Attribute’s state as a collection of values, and update it by adding, modifying, or removing individual elements
of the collection.
The “<attr_name>? and “set_<attr_name>? operations transfer an Attribute’s M1-level state using a “collection? type. This
is a named IDL sequence type whose base type is the Attribute’s M1-level base type, and whose name is determined
by the “name? of the Attribute’s “type? and the settings of the “isOrdered? and “isUnique? flags. For details, see 9.7.1.5,
“Literal String Values,? on page 200
.
The “<attr_name>? operation returns the multi-valued Attribute’s value as a sequence using the IDL type described above. The
contents of the result comprise the collection of base type instances related to the Instance object by the Class
— AttrType relation. If “isOrdered? is true, the order of the Class — AttrType relationships determines the order of the elements
in the sequence. If the collection is empty, the returned value is a zero length sequence.
The “set_<attr_name>? operation replaces the multi-valued Attribute’s value with a new collection of base type instances.
If the Attribute is ordered, the order of the elements in the parameter value determines the order of the new Class — AttrType
relationships.
A number of restrictions apply to the “set_<attr_name>? operation for multi-valued Attributes. These are as follows:
• If the Attribute’s “multiplicity? has the “isUnique? flag set to true, no two base type instances in the collection may be equal.
• If the Attribute’s “multiplicity? has an “upper? value other than the “UNBOUNDED? value (i.e., -1), there can be at most that many elements in the collection.
• If the Attribute’s “multiplicity? has a “lower? value greater than zero, there must be at least that many elements in the
collection.
If the Attribute has composite semantics (i.e., the Attribute’s “type? is expressed using a Class) the following restrictions
also apply:
• Each element (i.e., Instance object) in the new value collection must be either a reference to an existing Instance object or a nil object reference.
• No element of the new value collection can already be a component of another Instance object.
• The composite and every component Instance object must belong to the same outermost M1-level Package extent (i.e., the Composition Closure rule must not be violated).
• Creating the new Class — AttrType relationships must not create any composition cycles.
The IDL mapping can define up to 7 additional operations for a multi-valued Attribute. There are up to 3 operations for adding
new element values to an Attribute collection, up to 2 for modifying them and up to 2 for removing them. The subset that is
available for a given Attribute depends on the “isUnique? and “isOrdered? flags in the M2-level Attribute’s “multiplicity.?
This is shown in the table below.
isOrdered |
isUnique |
Operations available |
|||
false | false | add_<attr_name>, modify_<attr_name>, remove_<attr_name> | |||
false | true | add_<attr_name>, modify_<attr_name>, remove_<attr_name> | |||
true | false | add_<attr_name>, add_<attr_name>_before, add_<attr_name>_at, modify_<attr_name>, modify_<attr_name>_at, remove_<attr_name>, remove_<attr_name>_at | |||
true | true | add_<attr_name>, add_<attr_name>_before, modify_<attr_name>, remove_<attr_name> |
When “isOrdered? is set to false, the operations provided are the basic ones for adding, modifying, or removing element values.
Given that the collection is unordered, there is no need to specify the position at which a new element value is added, or
(in the false, false case) which of a number of equal element values should be modified or removed. The semantics of the operations
for an unordered Attribute are as follows:
• The “add_<attr_name>? operation creates a new Class — AttrType relationship between the Instance object and the M1-level base type instance being added to the Attribute collection.
• The “modify_<attr_name>? operation replaces the Class — AttrType relationship between the Instance object and the M1-level base type instance being modified with another for the new element value.
• The “remove_<attr_name>? operation removes the Class — AttrType relationship between the Instance object and the M1-level base type instance being removed from the Attribute collection. Removing the instance decreases the Attribute collection’s length rather than leaving a “hole.?
These three operations must also respect the restrictions listed above for the multi-valued “set_<attr_name>? operation.
When “isOrdered? is set to true, the “add_<attr_name>,? “modify_<attr_name>,? and “remove_<attr_name>? operations take on
additional semantics:
• The “add_<attr_name>? operation must ensure that the newly added element appears as the last element in the Attribute collection.
• The “modify_<attr_name>? operation must ensure that the replacement M1-level base type instance appears in the same position in the Attribute collection as the value that it replaces. When “isUnique? is set to false, the collection may contain duplicates. In this case, the operation should replace the first example of the instance in the ordered Attribute collection.
• When “isUnique? is set to false, the “remove_<attr_name>? operation should remove the first example of the instance in the ordered Attribute collection.
In addition, the client is provided with extra operations for order sensitive element update:
• The “add_<attr_name>_before? operation is similar to the “add_<attr_name>? operation, except that the new instance is added to the Attribute collection before an existing element designated by the caller. When “isUnique? is false, the operation is defined to replace the first example of the instance in the Attribute collection.
• When “isOrdered? is true and “isUnique? is false, the “add_<attr_name>_at,? “modify_<attr_name>_at,? and “remove_<attr_name>_at? are provided to allow the client to update the collection in the presence of duplicates. These operations specify an element insertion point or an element to be modified to be removed by giving a position index. For the purposes of these operations, the elements in an Attribute collection are numbered starting from zero according to the defined order of the members of the collection. The operations are as follows:
• add_<attr_name>_at - inserts the new M1-level base type instance so that it appears at the position given. The instance originally at that position, and all instances will have their position indexes increased by one. • modify_<attr_name>_at - replaces the M1-level base type instance at the position. • remove_<attr_name>_at - removes the M1-level base type instance at the position given. Any instances in the collection that follow the removed instance will have their position indexes decreased by one (i.e., the operation does not leave a “hole? in the Attribute collection).
These five additional operations must also respect the restrictions listed above for the multi-valued “set_<attr_name>? operation.
The previous semantic descriptions assume the M2-level Attribute has “isChangeable? set to true and “isDerived? set to false.
This sub clause describes what happens if this is not the case.
If an Attribute has “isChangeable? set to false, the effect on the IDL mapping is that all generated operations for updating
the Attribute’s state are suppressed. This does not preclude the existence of other mechanisms for updating the Attribute’s
state.
Setting an Attribute’s “isDerived? flag to true, has no effect on the IDL mapping. The operations generated for the derived
and non-derived cases are equivalent and they are defined to have equivalent semantics. If a derived Attribute’s operations
are coded by hand, it is the programmer’s responsibility to ensure that they implement the required semantics.
The previous semantic descriptions assume the M2-level Attribute has “scope? set to “instance_level.? When an Attribute’s
“scope? is “classifier_level,? we can model the notional relation that defines the M1-level Attribute state as a
relation between the Class extent and the AttrType; see 8.6.3, “Scope,? on page 143. In the IDL mapping, this translates
to a notional relation between a Class Proxy object and instances of the Attribute’s M1-level base type.
On this basis, an Attribute whose “scope? is “classifier_level? differs from one whose “scope? is “instance_level? in the
following respects:
• The notional Class Proxy — AttrType relation supplies the value or values accessed and updated by “classifier_level? scoped Attribute operations.
• When the Attribute has aggregation semantics of “composite?:
• the Composition Closure rule means that the Class Proxy object and M1-level Attribute value Instances must belong to the same extent, and • checking for composition cycles is unnecessary. The Class Proxy object that holds the Attribute value(s) is not an Instance, and thus cannot be a “component? in this sense.
The previous semantic descriptions apply equally to Attributes defined within an M2-level Class, and Attribute inherited from
supertypes of the Class.
The previous semantic descriptions say nothing about how an Attribute gets its initial value or values. (With the exception
of the single-valued case of the “<attr_name>? operation, the semantic descriptions would “work? if no notional relationships
existed initially.) In fact, the IDL mapping ensures that all M1-level Attributes get a client-supplied initial value:
• All “instance_level? scoped Attribute values for an M1-level Instance object are initialized from the parameters to the “create_<class_name>? operation.
• All “classifier_level? scoped Attribute values within the extent of an outermost M1-level Package are initialized from the parameters to the “create_<package_name>? operation.
An M1-level Attribute only exists while the M1-level Instance object or Class Proxy object that it belongs to exists. When
the object is deleted, the notional relationships disappear as well.
Attributes with “composite? aggregation semantics have special life-cycle. When an object with a composite Attribute is deleted,
the Instance object or objects that form its value are also deleted.
Note that unlike Associations, when an Instance object is deleted, the delete operation should make no attempt to tidy up
“dangling references? to it.
The IDL mapping maps References into a hybrid that combines an Attribute style interface with Association access and update
semantics. In each case, a Reference operation maps fairly directly onto an Association operation as shown in the table below.
Multiplicity | Reference Operation | Association Operation(s) (assuming that the referenced AssociationEnd is the 2nd one) | |||
optional | i.<reference_name>() | temp = a.<referenced_end_name>(i) if temp.size > 0 then temp[0] else raise NotSet | |||
single- and multi-valued | i.<reference_name>() | a.<referenced_end_name>(i) | |||
optional | i.set_<reference_name>(new) | old = a.<reference_end_name>(i) if old.size > 0 then a.modify_<reference_end_name>(i, old[0], new) else a.add(i, new) | |||
optional | i.unset_<reference_name>() | old = a.<reference_end_name>(i) if old.size > 0 then a.remove(i, old[0]) | |||
single-valued | i.set_<reference_name>(new) | old = a.<ref_end_name>(i) a.modify_<ref_end_name>(i, old, new) | |||
multi-valued | i.set_<reference_name>(new) | old = a.<ref_end_name>(i) for j in 0 .. (old.size - 1) do a.remove(i, old[j]) for j in 0 .. (old.size - 1) do a.add(i, new[j]) | |||
multi-valued | i.add_<reference_name>(new) | a.add(i, new) | |||
multi-valued | i.add_before_<reference_name>(new, before) | a.add_before_<referenced_end_name>(i, new, before) | |||
multi-valued | i.modify_<reference_name>(old, new) | a.modify_<referenced_end_name>(i, old, new) | |||
multi-valued | i.remove_<reference_name>(old) | a.remove_<referenced_end_name>(i, old) |
In practice, an implementation also needs to transform exceptions reported for the Association operations into exceptions
that apply from the Reference perspective. In addition, a “quality? implementation would ensure that Reference operations
did not leave the Association object in a half way state following an exception.
NOTE: The above semantic mapping description is not intended as implying any particular implementation approach.
© ISO/IEC 2005 - All rights reserved
The impact of clusters on the IDL mapping semantics are largely described elsewhere. At the M1-level, a clustered Package
behaves identically to a nested Package in terms of life-cycle and extent rules. The only significant difference is
that clustering is not always a strict composition relationship at the M1-level; see 8.8.4, “Package Extents,? on page 147.
In the IDL mapping, this means that two or more Package “ref? attributes point at the same clustered Package instance.
All operations defined by the IDL mapping (including the Reflective versions) are required to be atomic and idempotent:
• If an operation fails (e.g., by raising an exception), no externally visible changes should be caused by the failed operation.
• When the invocation of two or more operations overlap in time, the resultant behavior should be semantically equivalent to the sequential invocation of the operations in some order.
• If an operation succeeds, state changes required by the specification should be made, except as noted below:
• When an Instance object is deleted, deletion of any component Instance objects may occur asynchronously. • When an Instance object is deleted, removal of links to the deleted Instance object may occur asynchronously.
NOTE: The IDL mapping specification does not require a transactional or persistent implementation of a meta-data server.
The inheritance pattern for Instance and Class Proxy interfaces has an important consequence when one M2-level Class is a
sub-Class of a second one.
Recall that each Class Proxy interface defines a factory operation for the corresponding Instance object, and that it also
inherits from the Class Proxy interfaces for any M2-level super-Classes. Taken together, this means that any Class Proxy object
has operations for creating Instance objects for both the M2-level Class, and all of its M2-level super-Classes.
Normally, this artifact of the IDL inheritance hierarchy is just a convenience. However, problems arise when an M2-level
Class (e.g., P2::C2) has a super-Class that is imported from another M2-level Package (e.g., P1::C1); see Figure 9.3 on
page 183. The Class Proxy interface corresponding to the C2 Class now has a factory operation to create instances of a
Class from another Package, and therefore would appear to require all of the mechanisms for creating, accessing, updating,
and deleting these instances. This is not what Package importing is defined to mean.
The adopted solution to this problem is to add an extra restriction to the MOF computational semantics. This restriction is
known as the Supertype Closure Rule.
Supertype Closure Rule
Suppose that the Package extent for a non-nested M2-level Package P contains a Class Proxy object, which has a create operation
for instances of Class C. This create operation can be used if and only if the M2-level closure of the Package P under generalization
and clustering includes the M2-level Class C.
In other words, a factory operation for instances of an M2-level Class will only work within a Package instance with the machinery
for supporting the Class. The Supertype Closure Rule is illustrated in
Figure 9.3.
«imports»
«clusters»
Meta-model Definition
P1 Instance P2 Instance
C1 C1Proxy
Proxy C2 extent
C1
extent
P3 Instance
C1
Proxy
C1 extent C3 Proxy C3 extent
Figure 9.3 - Supertype Closure Rule
The IDL mapping currently defines no APIs for copying meta-data. Copy semantics are therefore beyond the scope of this clause.