VisiBroker for Java Developer’s Guide : Using the dynamically managed types

Using the dynamically managed types
This section describes the DynAny feature of VisiBroker, which allows you to construct and interpret data types at runtime.
DynAny interface overview
The DynAny interface provides a way to dynamically create basic and constructed data types at runtime. It also allows information to be interpreted and extracted from an Any object, even if the type it contains was not known to the server at compile-time. Using the DynAny interface, you can build powerful client and server applications that create and interpret data types at run time.
DynAny examples
Example client and server applications that illustrate the use of DynAny are included as part of the VisiBroker distribution. The examples are located in the following directory:
<install_dir>\examples\vbroker\dynany\
These example programs are used to illustrate DynAny concepts throughout this section.
DynAny types
A DynAny object has an associated value that may either be a basic data type (such as boolean, int, or float) or a constructed data type. The DynAny interface, its methods and classes are also documented in the VisiBroker API References. “Programmer tools for Java” provides methods for determining the type of the contained data as well as for setting and extracting the value of primitive data types.
Constructed data types are represented by the following interfaces, which are all derived from DynAny. Each of these interfaces provides its own set of methods that are appropriate for setting and extracting the values it contains.
DynAny usage restrictions
A DynAny object may only be used locally by the process which created it. Any attempt to use a DynAny object as a parameter on an operation request for a bound object or to externalize it using the ORB.object_to_string method will cause a MARSHAL exception to be raised.
Furthermore, any attempt to use a DynAny object as a parameter on DII request will cause a NO_IMPLEMENT exception to be raised.
This version does not support the long double and fixed types as specified in CORBA 3.0.
Creating a DynAny
A DynAny object is created by invoking an operation on a DynAnyFactory object. First obtain a reference to the DynAnyFactory object, and then use that object to create the new DynAny object.
// Resolve Dynamic Any Factory
DynAnyFactory factory =
DynAnyFactoryHelper.narrow(
orb.resolve_initial_references("DynAnyFactory"));
byte[] oid = "PrinterManager".getBytes();
// Create the printer manager object.
PrinterManagerImpl manager =
new PrinterManagerImpl((com.inprise.vbroker.CORBA.ORB) orb,
factory, serverPoa, oid);
// Export the newly create object.
serverPoa.activate_object_with_id(oid, manager);
System.out.println(manager + " is ready.");
Initializing and accessing the value in a DynAny
The DynAny.insert_<type> methods allow you to initialize a DynAny object with a variety of basic data types, where <type> is boolean, octet, char, and so on. Any attempt to insert a type that does not match the TypeCode defined for the DynAny will cause an TypeMismatch exception to be raised.
The DynAny.get_<type> methods allow you to access the value contained in a DynAny object, where <type> is boolean, octet, char, and so on. Any attempt to access a value from a DynAny component which does not match the TypeCode defined for the DynAny will cause a TypeMismatch exception to be raised.
The DynAny interface also provides methods for copying, assigning, and converting to or from an Any object. The sample programs, described in “DynAny example client application” and “DynAny example server application”, provide examples of how to use some of these methods.
Constructed data types
The following types are derived from the DynAny interface and are used to represent constructed data types.
Traversing the components in a constructed data type
Several of the interfaces that are derived from DynAny actually contain multiple components. The DynAny interface provides methods that allow you to iterate through these components. The DynAny-derived objects that contain multiple components maintain a pointer to the current component.
Returns a DynAny object, which may be narrowed to the appropriate type, based on the component's TypeCode.
Sets the current component pointer to the component with the specified, zero-based index. Returns false if there is no component at the specified index. Sets the current component pointer to -1 (no component) if specified with a negative index.
DynEnum
The DynEnum interface represents a single enumeration constant. Methods are provided for setting and obtaining the value as a string or as an integral value.
DynStruct
The DynStruct interface represents a dynamically constructed struct type. The members of the structure can be retrieved or set using a sequence of NameValuePair objects. Each NameValuePair object contains the member's name and an Any containing the member's Type and value.
You may use the rewind, next, current_component, and seek methods to traverse the members in the structure. Methods are provided for setting and obtaining the structure's members.
DynUnion
The DynUnion interface represents a union and contains two components. The first component represents the discriminator and the second represents the member value.
You may use the rewind, next, current_component, and seek methods to traverse the components. Methods are provided for setting and obtaining the union's discriminator and member value.
DynSequence and DynArray
A DynSequence or DynArray represents a sequence of basic or constructed data types without the need of generating a separate DynAny object for each component in the sequence or array. The number of components in a DynSequence may be changed, while the number of components in a DynArray is fixed.
You can use the rewind, next, current_component, and seek methods to traverse the members in a DynArray or DynSequence.
DynAny example IDL
The following code sample shows the IDL used in the example client and server applications. The StructType structure contains two basic data types and an enumeration value. The PrinterManager interface is used to display the contents of an Any without any static information about the data type it contains.
// Printer.idl
module Printer {
enum EnumType {first, second, third, fourth};
struct StructType {
string str;
EnumType e;
float fl;
};
interface PrinterManager {
void printAny(in any info);
oneway void shutdown();
};
};
DynAny example client application
The following code sample shows a client application that can be found in the following VisiBroker distribution directory:
<install_dir>\examples\vbroker\dynany\
The client application uses the DynStruct interface to dynamically create a StructType structure.
The DynStruct interface uses a sequence of NameValuePair objects to represent the structure members and their corresponding values. Each name-value pair consists of a string containing the structure member's name and an Any object containing the structure member's value.
After initializing the VisiBroker ORB in the usual manner and binding to a PrintManager object, the client performs the following steps:
1
Creates an empty DynStruct with the appropriate type.
2
Creates a sequence of NameValuePair objects that will contain the structure members.
3
Creates and initializes Any objects for each of the structure member's values.
4
Initializes each NameValuePair with the appropriate member name and value.
5
Initializes the DynStruct object with the NameValuePair sequence.
6
Invokes the PrinterManager.printAny method, passing the DynStruct converted to a regular Any.
Note
You must use the DynAny.to_any method to convert a DynAny object, or one of its derived types, to an Any before passing it as a parameter on an operation request.
 
The following code sample is an example of a client application that uses DynStruct:
// Client.java
import org.omg.DynamicAny.*;
public class Client {
public static void main(String[] args) {
try {
// Initialize the ORB.
org.omg.CORBA.ORB orb = org.omg.CORBA.ORB.init(args, null);
DynAnyFactory factory =
DynAnyFactoryHelper.narrow(
orb.resolve_initial_references("DynAnyFactory"));
// Locate a printer manager.
Printer.PrinterManager manager =
Printer.PrinterManagerHelper.bind(orb, "PrinterManager");
// Create Dynamic struct
DynStruct info =
DynStructHelper.narrow(factory.create_dyn_any_from_type_code
(Printer.StructTypeHelper.type()));
// Create our NameValuePair sequence (array)
NameValuePair[] NVPair = new NameValuePair[3];
// Create and initialize Dynamic Struct data as any's
org.omg.CORBA.Any str_any = orb.create_any();
str_any.insert_string("String");
org.omg.CORBA.Any e_any = orb.create_any();
Printer.EnumTypeHelper.insert(e_any, Printer.EnumType.second);
org.omg.CORBA.Any fl_any = orb.create_any();
fl_any.insert_float((float)864.50);
NVPair[0] = new NameValuePair("str", str_any);
NVPair[1] = new NameValuePair("e", e_any);
NVPair[2] = new NameValuePair("fl", fl_any);
// Initialize the Dynamic Struct
info.set_members(NVPair);
manager.printAny(info.to_any());
manager.shutdown();
}
catch (Exception e) {
e.printStackTrace();
}
}
}
DynAny example server application
The following code sample shows a server application that can be found in the following VisiBroker distribution directory:
<install_dir>\examples\vbroker\dynany\
The server application performs the following steps.
1
2
3
Creates a PrintManager object.
4
Exports the PrintManager object.
5
// Server.java
import java.util.*;
import org.omg.DynamicAny.*;
import org.omg.PortableServer.*;
import com.inprise.vbroker.PortableServerExt.*;
public class Server {
public static void main(String[] args) {
try {
// Initialize the ORB.
org.omg.CORBA.ORB orb = org.omg.CORBA.ORB.init(args,null);
// Resolve Root POA
POA rootPoa =
POAHelper.narrow(orb.resolve_initial_references(
"RootPOA"));
rootPoa.the_POAManager().activate();
// Create a BindSupport Policy that makes POA register
// each servant with osagent
org.omg.CORBA.Any any = orb.create_any();
BindSupportPolicyValueHelper.insert(any,
BindSupportPolicyValue.BY_INSTANCE);
org.omg.CORBA.Policy bsPolicy =
orb.create_policy(BIND_SUPPORT_POLICY_TYPE.value, any);
// Create policies for our testPOA
org.omg.CORBA.Policy[] policies = {
rootPoa.create_lifespan_policy(LifespanPolicyValue.PERSISTENT),
bsPolicy
};
// Create managerPOA with the right policies
      POA serverPoa =
rootPoa.create_POA(
"serverPoa",
rootPoa.the_POAManager(),
policies );
// Resolve Dynamic Any Factory
DynAnyFactory factory =
DynAnyFactoryHelper.narrow(
orb.resolve_initial_references("DynAnyFactory"));
byte[] oid = "PrinterManager".getBytes();
// Create the printer manager object.
PrinterManagerImpl manager =
new PrinterManagerImpl((
com.inprise.vbroker.CORBA.ORB) orb,
factory,
serverPoa,
oid);
// Export the newly create object.
serverPoa.activate_object_with_id(oid, manager);
System.out.println(manager + " is ready.");
// Wait for incoming requests
orb.run();
}
catch (Exception e) {
e.printStackTrace();
}
}
}
The following code sample shows how the PrinterManager implementation follows these steps in using a DynAny to process the Any object, without any compile-time knowledge of the type the Any contains.
1
Creates a DynAny object, initializing it with the received Any.
2
Performs a switch on the DynAny object's type.
3
If the DynAny contains a basic data type, simply prints out the value.
4
If the DynAny contains an Any type, creates a DynAny for it, determines it's contents, and then prints out the value.
5
If the DynAny contains an enum, creates a DynEnum for it and then prints out the string value.
6
If the DynAny contains a union, creates a DynUnion for it and then prints out the union's discriminator and the member.
7
If the DynAny contains a struct, array, or sequence, traverses through the contained components and prints out each value.
// PrinterManagerImpl.java
import java.util.*;
import org.omg.DynamicAny.*;
import org.omg.PortableServer.*;
public class PrinterManagerImpl extends Printer.PrinterManagerPOA {
private com.inprise.vbroker.CORBA.ORB _orb;
private DynAnyFactory _factory;
private POA _poa;
private byte[] _oid;
  public PrinterManagerImpl(com.inprise.vbroker.CORBA.ORB orb,
DynAnyFactory factory, POA poa, byte[] oid) {
_orb = orb;
_factory = factory;
_poa = poa;
_oid = oid;
}
public synchronized void printAny(org.omg.CORBA.Any info) {
// Display info with the assumption that we don't have
// any info statically about the type inside the any
try {
// Create a DynAny object
DynAny dynAny = _factory.create_dyn_any(info);
display(dynAny);
}
catch (Exception e) {
e.printStackTrace();
}
}
public void shutdown() {
try {
_poa.deactivate_object(_oid);
System.out.println("Server shutting down");
_orb.shutdown(false);
}
catch (Exception e) {
System.out.println(e);
}
}
private void display(DynAny value) throws Exception {
switch(value.type().kind().value()) {
case org.omg.CORBA.TCKind._tk_null:
case org.omg.CORBA.TCKind._tk_void: {
break;
}
case org.omg.CORBA.TCKind._tk_short: {
System.out.println(value.get_short());
break;
}
case org.omg.CORBA.TCKind._tk_ushort: {
System.out.println(value.get_ushort());
break;
}
case org.omg.CORBA.TCKind._tk_long: {
System.out.println(value.get_long());
break;
}
case org.omg.CORBA.TCKind._tk_ulong: {
System.out.println(value.get_ulong());
break;
}
case org.omg.CORBA.TCKind._tk_float: {
System.out.println(value.get_float());
break;
}
case org.omg.CORBA.TCKind._tk_double: {
System.out.println(value.get_double());
break;
}
      case org.omg.CORBA.TCKind._tk_boolean: {
System.out.println(value.get_boolean());
break;
}
case org.omg.CORBA.TCKind._tk_char: {
System.out.println(value.get_char());
break;
}
case org.omg.CORBA.TCKind._tk_octet: {
System.out.println(value.get_octet());
break;
}
case org.omg.CORBA.TCKind._tk_string: {
System.out.println(value.get_string());
break;
}
case org.omg.CORBA.TCKind._tk_any: {
DynAny dynAny = _factory.create_dyn_any(value.get_any());
display(dynAny);
break;
}
case org.omg.CORBA.TCKind._tk_TypeCode: {
System.out.println(value.get_typecode());
break;
}
case org.omg.CORBA.TCKind._tk_objref: {
System.out.println(value.get_reference());
break;
}
case org.omg.CORBA.TCKind._tk_enum: {
DynEnum dynEnum = DynEnumHelper.narrow(value);
System.out.println(dynEnum.get_as_string());
break;
}
case org.omg.CORBA.TCKind._tk_union: {
DynUnion dynUnion = DynUnionHelper.narrow(value);
display(dynUnion.get_discriminator());
display(dynUnion.member());
break;
}
case org.omg.CORBA.TCKind._tk_struct:
case org.omg.CORBA.TCKind._tk_array:
case org.omg.CORBA.TCKind._tk_sequence: {
value.rewind();
boolean next = true;
while(next) {
DynAny d = value.current_component();
display(d);
next = value.next();
}
break;
}
case org.omg.CORBA.TCKind._tk_longlong: {
System.out.println(value.get_longlong());
break;
}
case org.omg.CORBA.TCKind._tk_ulonglong: {
System.out.println(value.get_ulonglong());
break;
}
case org.omg.CORBA.TCKind._tk_wstring: {
System.out.println(value.get_wstring());
break;
}
case org.omg.CORBA.TCKind._tk_wchar: {
System.out.println(value.get_wchar());
break;
}
default:
System.out.println("Invalid type");

}
}
}