
- •Advanced CORBA® Programming with C++
- •Review
- •Dedication
- •Preface
- •Prerequisites
- •Scope of this Book
- •Acknowledgments
- •Chapter 1. Introduction
- •1.1 Introduction
- •1.2 Organization of the Book
- •1.3 CORBA Version
- •1.4 Typographical Conventions
- •1.5 Source Code Examples
- •1.6 Vendor Dependencies
- •1.7 Contacting the Authors
- •Part I: Introduction to CORBA
- •Chapter 2. An Overview of CORBA
- •2.1 Introduction
- •2.2 The Object Management Group
- •2.3 Concepts and Terminology
- •2.4 CORBA Features
- •2.5 Request Invocation
- •2.6 General CORBA Application Development
- •2.7 Summary
- •Chapter 3. A Minimal CORBA Application
- •3.1 Chapter Overview
- •3.2 Writing and Compiling an IDL Definition
- •3.3 Writing and Compiling a Server
- •3.4 Writing and Compiling a Client
- •3.5 Running Client and Server
- •3.6 Summary
- •Part II: Core CORBA
- •Chapter 4. The OMG Interface Definition Language
- •4.1 Chapter Overview
- •4.2 Introduction
- •4.3 Compilation
- •4.4 Source Files
- •4.5 Lexical Rules
- •4.6 Basic IDL Types
- •4.7 User-Defined Types
- •4.8 Interfaces and Operations
- •4.9 User Exceptions
- •4.10 System Exceptions
- •4.11 System Exceptions or User Exceptions?
- •4.12 Oneway Operations
- •4.13 Contexts
- •4.14 Attributes
- •4.15 Modules
- •4.16 Forward Declarations
- •4.17 Inheritance
- •4.18 Names and Scoping
- •4.19 Repository Identifiers and pragma Directives
- •4.20 Standard Include Files
- •4.21 Recent IDL Extensions
- •4.22 Summary
- •Chapter 5. IDL for a Climate Control System
- •5.1 Chapter Overview
- •5.2 The Climate Control System
- •5.3 IDL for the Climate Control System
- •5.4 The Complete Specification
- •Chapter 6. Basic IDL-to-C++ Mapping
- •6.1 Chapter Overview
- •6.2 Introduction
- •6.3 Mapping for Identifiers
- •6.4 Mapping for Modules
- •6.5 The CORBA Module
- •6.6 Mapping for Basic Types
- •6.7 Mapping for Constants
- •6.8 Mapping for Enumerated Types
- •6.9 Variable-Length Types and _var Types
- •6.10 The String_var Wrapper Class
- •6.11 Mapping for Wide Strings
- •6.12 Mapping for Fixed-Point Types
- •6.13 Mapping for Structures
- •6.14 Mapping for Sequences
- •6.15 Mapping for Arrays
- •6.16 Mapping for Unions
- •6.17 Mapping for Recursive Structures and Unions
- •6.18 Mapping for Type Definitions
- •6.19 User-Defined Types and _var Classes
- •6.20 Summary
- •Chapter 7. Client-Side C++ Mapping
- •7.1 Chapter Overview
- •7.2 Introduction
- •7.3 Mapping for Interfaces
- •7.4 Object Reference Types
- •7.5 Life Cycle of Object References
- •7.6 Semantics of _ptr References
- •7.7 Pseudo-Objects
- •7.8 ORB Initialization
- •7.9 Initial References
- •7.10 Stringified References
- •7.11 The Object Pseudo-Interface
- •7.12 _var References
- •7.13 Mapping for Operations and Attributes
- •7.14 Parameter Passing Rules
- •7.15 Mapping for Exceptions
- •7.16 Mapping for Contexts
- •7.17 Summary
- •Chapter 8. Developing a Client for the Climate Control System
- •8.1 Chapter Overview
- •8.2 Introduction
- •8.3 Overall Client Structure
- •8.4 Included Files
- •8.5 Helper Functions
- •8.6 The main Program
- •8.7 The Complete Client Code
- •8.8 Summary
- •Chapter 9. Server-Side C++ Mapping
- •9.1 Chapter Overview
- •9.2 Introduction
- •9.3 Mapping for Interfaces
- •9.4 Servant Classes
- •9.5 Object Incarnation
- •9.6 Server main
- •9.7 Parameter Passing Rules
- •9.8 Raising Exceptions
- •9.9 Tie Classes
- •9.10 Summary
- •Chapter 10. Developing a Server for the Climate Control System
- •10.1 Chapter Overview
- •10.2 Introduction
- •10.3 The Instrument Control Protocol API
- •10.4 Designing the Thermometer Servant Class
- •10.5 Implementing the Thermometer Servant Class
- •10.6 Designing the Thermostat Servant Class
- •10.7 Implementing the Thermostat Servant Class
- •10.8 Designing the Controller Servant Class
- •10.9 Implementing the Controller Servant Class
- •10.10 Implementing the Server main Function
- •10.11 The Complete Server Code
- •10.12 Summary
- •Chapter 11. The Portable Object Adapter
- •11.1 Chapter Overview
- •11.2 Introduction
- •11.3 POA Fundamentals
- •11.4 POA Policies
- •11.5 POA Creation
- •11.6 Servant IDL Type
- •11.7 Object Creation and Activation
- •11.8 Reference, ObjectId, and Servant
- •11.9 Object Deactivation
- •11.10 Request Flow Control
- •11.11 ORB Event Handling
- •11.12 POA Activation
- •11.13 POA Destruction
- •11.14 Applying POA Policies
- •11.15 Summary
- •Chapter 12. Object Life Cycle
- •12.1 Chapter Overview
- •12.2 Introduction
- •12.3 Object Factories
- •12.4 Destroying, Copying, and Moving Objects
- •12.5 A Critique of the Life Cycle Service
- •12.6 The Evictor Pattern
- •12.7 Garbage Collection of Servants
- •12.8 Garbage Collection of CORBA Objects
- •12.9 Summary
- •Part III: CORBA Mechanisms
- •Chapter 13. GIOP, IIOP, and IORs
- •13.1 Chapter Overview
- •13.2 An Overview of GIOP
- •13.3 Common Data Representation
- •13.4 GIOP Message Formats
- •13.5 GIOP Connection Management
- •13.6 Detecting Disorderly Shutdown
- •13.7 An Overview of IIOP
- •13.8 Structure of an IOR
- •13.9 Bidirectional IIOP
- •13.10 Summary
- •14.1 Chapter Overview
- •14.2 Binding Modes
- •14.3 Direct Binding
- •14.4 Indirect Binding via an Implementation Repository
- •14.5 Migration, Reliability, Performance, and Scalability
- •14.6 Activation Modes
- •14.7 Race Conditions
- •14.8 Security Considerations
- •14.9 Summary
- •Part VI: Dynamic CORBA
- •Chapter 15 C++ Mapping for Type any
- •15.1 Chapter Overview
- •15.2 Introduction
- •15.3 Type any C++ Mapping
- •15.4 Pitfalls in Type Definitions
- •15.5 Summary
- •Chapter 16. Type Codes
- •16.1 Chapter Overview
- •16.2 Introduction
- •16.3 The TypeCode Pseudo-Object
- •16.4 C++ Mapping for the TypeCode Pseudo-Object
- •16.5 Type Code Comparisons
- •16.6 Type Code Constants
- •16.7 Type Code Comparison for Type any
- •16.8 Creating Type Codes Dynamically
- •16.9 Summary
- •Chapter 17. Type DynAny
- •17.1 Chapter Overview
- •17.2 Introduction
- •17.3 The DynAny Interface
- •17.4 C++ Mapping for DynAny
- •17.5 Using DynAny for Generic Display
- •17.6 Obtaining Type Information
- •17.7 Summary
- •Part V: CORBAservices
- •Chapter 18. The OMG Naming Service
- •18.1 Chapter Overview
- •18.2 Introduction
- •18.3 Basic Concepts
- •18.4 Structure of the Naming Service IDL
- •18.5 Semantics of Names
- •18.6 Naming Context IDL
- •18.7 Iterators
- •18.8 Pitfalls in the Naming Service
- •18.9 The Names Library
- •18.10 Naming Service Tools
- •18.11 What to Advertise
- •18.12 When to Advertise
- •18.13 Federated Naming
- •18.14 Adding Naming to the Climate Control System
- •18.15 Summary
- •Chapter 19. The OMG Trading Service
- •19.1 Chapter Overview
- •19.2 Introduction
- •19.3 Trading Concepts and Terminology
- •19.4 IDL Overview
- •19.5 The Service Type Repository
- •19.6 The Trader Interfaces
- •19.7 Exporting Service Offers
- •19.8 Withdrawing Service Offers
- •19.9 Modifying Service Offers
- •19.10 The Trader Constraint Language
- •19.11 Importing Service Offers
- •19.12 Bulk Withdrawal
- •19.13 The Admin Interface
- •19.14 Inspecting Service Offers
- •19.15 Exporting Dynamic Properties
- •19.16 Trader Federation
- •19.17 Trader Tools
- •19.18 Architectural Considerations
- •19.19 What to Advertise
- •19.20 Avoiding Duplicate Service Offers
- •19.21 Adding Trading to the Climate Control System
- •19.22 Summary
- •Chapter 20. The OMG Event Service
- •20.1 Chapter Overview
- •20.2 Introduction
- •20.3 Distributed Callbacks
- •20.4 Event Service Basics
- •20.5 Event Service Interfaces
- •20.6 Implementing Consumers and Suppliers
- •20.7 Choosing an Event Model
- •20.8 Event Service Limitations
- •20.9 Summary
- •Part VI: Power CORBA
- •Chapter 21. Multithreaded Applications
- •21.1 Chapter Overview
- •21.2 Introduction
- •21.3 Motivation for Multithreaded Programs
- •21.4 Fundamentals of Multithreaded Servers
- •21.5 Multithreading Strategies
- •21.6 Implementing a Multithreaded Server
- •21.7 Servant Activators and the Evictor Pattern
- •21.8 Summary
- •22.1 Chapter Overview
- •22.2 Introduction
- •22.3 Reducing Messaging Overhead
- •22.4 Optimizing Server Implementations
- •22.5 Federating Services
- •22.6 Improving Physical Design
- •22.7 Summary
- •Appendix A. Source Code for the ICP Simulator
- •Appendix B. CORBA Resources
- •Bibliography

IT-SC book: Advanced CORBA® Programming with C++
Another potential problem of additional properties is that because there is no type definition for the property, the trader cannot enforce type consistency. Instead, for additional properties, it accepts values of any type at all. This places the burden of maintaining type consistency on the developer. For example, in the code example on page 864, we used an additional property called Description and gave it a string value. If we create a number of such service offers, we could supply a floating-point number as the value of the Description property in some of these offers (most likely because of a bug in the code). This can create havoc: half the offers in the trader might have a string in the Description property, whereas the other half might contain floating-point values. What happens when we formulate a query using this property is undefined in this case.
Because of the potential pitfalls with additional properties, we recommend that you use the feature with caution. If you decide to use additional properties, take care that value types are consistent. Otherwise, queries will yield unpredictable results.
19.8 Withdrawing Service Offers
The withdraw operation deletes a service offer from the trader:
// In module CosTrading...
exception IllegalOfferId { OfferId id;
};
exception UnknownOfferId { OfferId id;
};
exception ProxyOfferId { OfferId id;
};
// ...
interface Register : TraderComponents, SupportAttributes { // ...
void withdraw(in OfferId id) raises( IllegalOfferId, UnknownOfferId, ProxyOfferId
);
// ...
};
The id parameter passed to withdraw is an offer ID previously returned by an export operation on the same trader. The operation raises UnknownOfferId if the id parameter identifies a non-existent service offer. IllegalOfferId indicates that
746

IT-SC book: Advanced CORBA® Programming with C++
the offer ID does not conform to whatever syntax is used by the trader for its offer IDs. Attempts to delete a proxy offer by calling withdraw raise a ProxyOfferId exception. To delete a proxy offer, you must use the Proxy::withdraw_proxy operation.
19.9 Modifying Service Offers
You can use the Register::modify operation to change the property values of a service offer in place:
//In module CosTrading...
exception NotImplemented {};
//...
interface Register : TraderComponents, SupportAttributes {
// ...
exception ReadonlyProperty { |
|
||
|
ServiceTypeName type; |
|
|
}; |
PropertyName |
name; |
|
|
|
|
|
void |
modify( |
id, |
|
|
|
in OfferId |
|
|
|
in PropertyNameSeq |
del_list, |
|
|
in PropertySeq |
modify_list |
) raises(
NotImplemented, IllegalOfferId,
UnknownOfferId, ProxyOfferId, IllegalPropertyName, UnknownPropertyName, PropertyTypeMismatch, ReadonlyDynamicProperty, MandatoryProperty, ReadonlyProperty, DuplicatePropertyName
);
// ...
};
You can use modify to add optional properties to an existing offer, to change the value of existing modifiable properties, and to delete existing optional and modifiable properties. You are not allowed to delete an optional but read-only property because doing so would allow you to modify a read-only property by deleting it and adding it again with a new value.
The modify operation requires three parameters. id
This parameter identifies the service offer to modify by specifying the offer ID returned from the export operation used to create the offer.
del_list
747

IT-SC book: Advanced CORBA® Programming with C++
This parameter contains a sequence of property names. Properties whose names are on this sequence are removed from the service offer.
modify_list
This parameter supplies names and values for properties to be added or changed.
As you can see, the operation can raise a number of exceptions. The NotImplemented exception is raised by traders that do not support modifiable properties. (For such traders, the supports_modifiable_properties attribute on the
SupportAttributes interface is false.) The remaining exceptions have the same meaning as with the export and withdraw operations.
19.10 The Trader Constraint Language
Before we can look at how to import service offers, we must examine the trader constraint language. To select the service offers to be returned, the importer specifies a constraint using the constraint language. The constraint is a Boolean expression over the properties of service offers that have a nominated service type or have a service type derived from the nominated type. The trader matches service offers against the constraint. Those service offers that match become candidates to be returned from an import operation.
Note that the trader is free to return service offers that have a derived service type because derived service types guarantee two things: first, the IDL interface type of the object reference inside a derived service offer is compatible with that of the base service type; second, a derived service offer has all the properties defined in its base service type. In our controller example, these guarantees mean that if the importer asks for a controller, the trader is also free to return matching multiprotocol controllers because a multiprotocol controller can do everything an ordinary controller can. (You can suppress this polymorphic behavior by setting an import policy. However, suppressing polymorphism is generally a bad idea; the feature is provided mainly for trader maintenance purposes.)
19.10.1 Literals
The constraint language uses the same syntax as IDL for integer and floating-point literals. For example, -10.068E5 is a valid floating-point literal, and 999 is a valid integer literal.
Boolean literals are also the same as in IDL: TRUE and FALSE. The simplest possible constraint expression is TRUE—it matches all service offers.
Character literals differ from their IDL counterparts. The trader constraint language, like IDL, uses single quotation marks to delimit character literals but does not support the same escape sequences. The following are all valid character literals:
'A'
748

IT-SC book: Advanced CORBA® Programming with C++
' '
'\''
'\\'
You can include a literal single quotation mark by escaping it with a backslash, and you can include a literal backslash by escaping it with another backslash. There are no other escape sequences, so a literal such as '\023' is illegal.[3]
[3] A future revision of the specification may permit such escape sequeces.
String literals are also delimited by single quotation marks. Here are a few legal string literals:
'A'
'Hello World' 'Isn\'t this nice?'
'Literal backslash: \\'
The escape sequence conventions are the same as for character literals, so the only legal escape sequences are \' and \\. Note that a single-character literal, such as 'A', is both a legal character literal and a legal string literal. The trader uses the context in which the literal appears to deduce its type.
19.10.2 Identifiers
Whenever an identifier appears in a constraint, it refers to a property name. Identifiers follow the syntax for IDL identifiers. Because the properties are the only thing that can be named in a constraint, identifiers cannot be qualified using a :: operator (there is never a need to qualify them).
19.10.3 Comparison Operators
The constraint language provides the usual comparison operators:
==
!=
<
>
<=
>=
These operators have the same meaning as they do in C++. All of them can be applied to numeric types, strings, characters, and Boolean values. For strings and characters, comparisons use the ISO Latin-1 collating sequence. For Boolean comparisons, TRUE is greater than FALSE.
19.10.4 Arithmetic Operators
749

IT-SC book: Advanced CORBA® Programming with C++
The constraint language supports the following arithmetic operators:
+
-
*
/
The - operator is both unary and binary. There is no modulo operator. The arithmetic operators apply to integer and floating-point types. Mixed-mode arithmetic is supported. The trader applies type promotion rules to permit mixed-mode arithmetic, but the specification does not spell out these type promotion rules. You should be careful about conditions such as overflow, underflow, and value truncation because the results are implementation-dependent.
19.10.5 Boolean Operators
The constraint language provides the Boolean operators and, or, and not. These operators are reserved words, so do not create properties with these names; otherwise, you will not be able to use them in queries. For example, if you create a property called and, there is no way to use that property name in an expression because it will result in a syntax error.
19.10.6 Set Membership
The in operator tests for set membership. The left-hand operand must be an integer, floating-point, character, string, or Boolean value. The right-hand operand must be a sequence of elements of the type of the left-hand operand. For example:
'Visa' in CreditCards
The in operator returns true if CreditCards is a property of type sequence of string and if 'Visa' appears as one of the elements of the sequence. Note that the in operator cannot test for set membership of an enumerated value in a sequence.
19.10.7 Substring Matching
The ~ operator tests whether the string on the left appears as a substring of the string on the right. The match is always a literal string match; there are no wild cards or regular expressions. Here is a simple example:
'part' ~ 'departments'
This expression returns true. Either the left-hand or the right-hand (or both) operands can be identifiers that name a property, so the following is legal:
'90' ~ Model
750

IT-SC book: Advanced CORBA® Programming with C++
This expression returns true if 90 appears anywhere in the Model string property.
19.10.8 Testing for Existence
The exist operator is a unary operator. It returns true if the property named by its righthand argument exists. For example:
exist Model
The exist operator permits you to test for the existence of optional properties:
exist Model and Model == 'BFG-9000'
This expression returns true if a service offer has the optional Model property and if that property's value is 'BFG-9000'. Strictly speaking, the exist operator is redundant in the preceding expression. We could also write
Model == 'BFG-9000'
This has the same meaning because all comparison operators return false if they are applied to an optional property that does not exist in a service offer. As a result, the exist operator is required only if you want to locate service offers that have an optional property without specifying a value for that property.
19.10.9 Precedence
The operators for the constraint language have the following precedence, from highest to lowest (operators on the same line have the same precedence):
exist - (unary minus) not
* / + -
~
in
== != < <= > >= and
or
You can use parentheses to override precedence as necessary.
19.10.10 Constraint Language Example
Here again is the query from page 831:
751