Introduction
This is part II of the Using CORBA AppWizard tutorial. The first part of the tutorial dealt with the
Application Wizard steps. This part will complete the tutorial by implementing
the Stock Quoter application.
Completing the Applications
Now that the framework for the application has been generated and the
workspace is display by the IDE, we can add code and complete the Quoter
application. Of all the files that are shown in the view only the
StdAfx.cpp, StdAfx.h and QuoterServer.cpp contain code. All
the others files are basically empty except for displaying the following
message:
So lets get started:
Now open the Quoter.idl file. It should contain the following:
#ifndef Quoter_module
#define Quoter_module
module Quoter
{
interface Stock
{
};
interface StockFactory
{
};
};
#endif
First we need to define the interfaces. We will start with the
Stock
interface, where a function that will be used to find out the
price of a stock is the first that we will deal with. (The code in bold is what
needs to be added).
interface Stock
{
double price();
};
Each stock also has a name and symbol associated with it, which we can call
the attributes of the stock. So lets add these attributes, and so that the user
can only enquire about them and not set them we will make them read-only:
interface Stock
{
double price();
readonly attribute string symbol;
readonly attribute string full_name;
};
To get the stock object that corresponds to a specific symbol we need to use
the StockFactory
interface and add a function that takes a symbol
as an argument and returns the stock associated with that symbol. However if an
invalid symbol is passed as a parameter to this function, then an error will
occur. The error raised will be in the form of an exception.
module Quoter
{
exception Invalid_Stock_Symbol {};
interface Stock
....
interface StockFactory
{
Stock get_stock(in string stock_symbol) raises (Invalid_Stock_Symbol);
};
Now the Quoter.idl can be compiled. The compilation is done by the
TAO_IDL compiler. If all goes well the empty files will now contain various
forms of code when opened. The code produced in some files is in the form of a
skeleton to which you need to add the meat.
Open the QuoterI.cpp and the QuoterI.h files. This is where the
interfaces that are found in the Quoter.idl will be implemented. There is
no need to open any of the other files e.g. QuoterS.cpp
consists of CORBA related skeleton code, QuoterC.cpp consists of
CORBA related stub code and will most likely give you nightmares. First lets
look at the QuoterI.h file. The Stock
interface is
implemented by the Quoter_Stock_i
class while the
StockFactory
interface is implemented by the
Quoter_StockFactory_i
class. We will first look at the
Quoter_Stock_i
class and then at the
Quoter_StockFactory_i
class (again the code in bold is what needs
to be entered by you).
class Quoter_Stock_i : public virtual POA_Quoter::Stock
{
public:
Quoter_Stock_i (const char* symbol, const char* full_name,
CORBA::Double price);
...
private:
std::string symbol_;
std::string full_name_;
CORBA::Double price_;
}
The StockFactory will only have two stocks: RHAT and MSFT.
class Quoter_StockFactory_i : public virtual POA_Quoter::StockFactory
{
public:
...
private:
Quoter_Stock_i rhat_;
Quoter_Stock_i msft_;
};
Now lets look at the QuoterI.cpp file where the functions shown above
will be implemented.
Lets concentrate on the Quoter_Stock_i
class. First the constructor.
Quoter_Stock_i::Quoter_Stock_i (const char *symbol, const char *full_name,
CORBA::Double price)
: symbol_ (symbol), full_name_ (full_name), price_ (price)
{
}
First we will implement the functions declared in the
Quoter_Stock_i
class:
- The
symbol()
function. This function returns the symbol
associated with the stock.
char* Quoter_Stock_i::symbol() throw (CORBA::SystemException)
{
return CORBA::string_dup(this->symbol_.c_str());
}
- The
full_name()
function. This function returns the name
associated with the stock.
char* Quoter_Stock_i::full_name() throw (CORBA::SystemException)
{
return CORBA::string_dup(this->full_name_.c_str());
}
- The
price()
function. This function returns the current price
of the stock.
CORBA::Double Quoter_Stock_i::price() throw (CORBA::SystemException)
{
return this->price_;
}
Now it is the turn of the Quoter_StockFactory_i
class. There is
only one function, namely get_stock()
that needs implementing.
Quoter::Stock_ptr Quoter_StockFactory_i::get_stock(
const char * stock_symbol) throw
(CORBA::SystemException, Quoter::Invalid_Stock_Symbol)
{
if (strcmp (symbol, "RHAT") == 0)
{
return this->rhat_._this();
}
else if (strcmp (symbol, "MSFT") == 0)
{
return this->msft_._this ();
}
throw Quoter::Invalid_Stock_Symbol ();
}
The Quoter_StockFactory_i
constructor also needs some changes.
Quoter_StockFactory_i::Quoter_StockFactory_i()
: rhat_("RHAT", "RedHat, Inc.", 210), msft_("MSFT", "Microsoft, Inc.", 91)
{
}
Finally we turn to the QuoterServer.cpp file (QuoterServer is the name
I gave to the project, so whatever you named your project look for a file with
that name and a .cpp extension) and look at the main()
function.
Quoter_StockFactory_i stock_factory_i;
Quoter::StockFactory_var stock_factory = stock_factory_i._this();
CORBA::String_var ior = orb->object_to_string(stock_factory.in());
cout << ior.in() << endl;
Now it is time to build the server application. But first a warning, don't go
and click on the Build toolbar button! The problem is that the Quoter.idl
file will be compiled again and any changes that you have made to the
QuoterI.h and QuoterI.cpp files will have been replaced by the
skeleton code produced by the TAO_IDL compiler. Rather highlight the
StdAfx.cpp file and compile it. Follow that by the separate compilation
of the QuoterI.cpp and QuoterServer.cpp files respectively. Now
you can click on the Build toolbar button.
The idl file is the same as that for the Server
application. So just copy the Quoter.idl file from the directory of
the Server application and copy it into the directory of the Client application.
Open the Quoter.idl file and compile it. Once again the TAO_IDL compiler
will be used. Initially the QuoterC.cpp file will be empty but after
compilation will contain the CORBA stub code. For the client side of the Stock
Quoter application we only need to look at the main()
function
(Remember the code in bold is what you need to enter).
Quoter::StockFactory_var factory =
Quoter::StockFactory::_narrow(obj.in());
for (int i = 2; i != argc; i++)
{
try
{
Quoter::Stock_var stock = factory->get_stock(argv[i]);
CORBA::String_var name = stock->full_name();
CORBA::Double price = stock->price();
cout << "The price of stock in \"" << name.in() << "\" is $"
<< price << endl;
}
catch(Quoter::Invalid_Stock_Symbol&)
{
cerr << "Invalid stock symbol <" << argv[i] << ">" << endl;
}
}
orb->destroy();
Lets now build the client application, but in
comparison to the server application one can click on the Build toolbar button
immediately.
Now that you have compiled and built both the server and client applications,
it is time to run the Stock Quoter application and see if everything works. Open
two DOS prompt windows. In the first window write:
server > ior_file
and leave the window open. The image below shows what I typed on my
computer.
In the second window write:
client file://ior_file MSFT RHAT HALO
and then press Return. The image below shows the command and
result on my computer. Note that we didn't implement HALO as a stock in the
StockFactory
and therefore the error message.
Comments
If you have any comments or find any bugs please let me know.
History
- 3 November 2003 - First public release.