Merge pull request #1844 from jrw972/monterey
[ACE_TAO.git] / TAO / examples / Advanced / ch_18 / client.cpp
blobc7603921699d1d14c16f1861a8392010c98d3c43
1 //=============================================================================
2 /**
3 * @file client.cpp
5 * @author Source code used in TAO has been modified and adapted from the codeprovided in the book
6 * @author "Advanced CORBA Programming with C++" by MichiHenning and Steve Vinoski. Copyright 1999. Addison-Wesley
7 * @author Reading
8 * @author MA.Modified for TAO by Mike Moran <mm4@cs.wustl.edu>
9 */
10 //=============================================================================
13 #include "CCSC.h" // ORB-specific
14 #include "assert.h"
15 #include <orbsvcs/CosNamingC.h>
16 #include <ace/streams.h>
17 // ----------------------------------------------------------------
19 using namespace std;
21 template<class T>
22 typename T::_ptr_type
23 resolve_init(CORBA::ORB_ptr orb, const char * id)
25 CORBA::Object_var obj;
26 try {
27 obj = orb->resolve_initial_references(id);
29 catch (const CORBA::ORB::InvalidName &) {
30 throw;
32 catch (const CORBA::Exception & e) {
33 std::cerr << "Cannot get initial reference for "
34 << id << ": "
35 << e
36 << std::endl;
37 throw 0;
39 assert(!CORBA::is_nil(obj.in()));
41 typename T::_var_type ref;
42 try {
43 ref = T::_narrow(obj.in());
45 catch (const CORBA::Exception & e) {
46 std::cerr << "Cannot narrow reference for "
47 << id << ": "
48 << e
49 << std::endl;
50 throw 0;
52 if (CORBA::is_nil(ref.in())) {
53 std::cerr << "Incorrect type of reference for "
54 << id << std::endl;
55 throw 0;
57 return ref._retn();
60 //----------------------------------------------------------------
62 template<class T>
63 typename T::_ptr_type
64 resolve_name(
65 CosNaming::NamingContext_ptr nc,
66 const CosNaming::Name & name)
68 CORBA::Object_var obj;
69 try {
70 obj = nc->resolve(name);
72 catch (const CosNaming::NamingContext::NotFound &) {
73 throw;
75 catch (const CORBA::Exception & e) {
76 std::cerr << "Cannot resolve binding: "
77 << e
78 << std::endl;
79 throw 0;
81 if (CORBA::is_nil(obj.in())) {
82 std::cerr << "Nil binding in Naming Service" << std::endl;
83 throw 0;
86 typename T::_var_type ref;
87 try {
88 ref = T::_narrow(obj.in());
90 catch (const CORBA::Exception & e) {
91 std::cerr << "Cannot narrow reference: "
92 << e
93 << std::endl;
94 throw 0;
96 if (CORBA::is_nil(ref.in())) {
97 std::cerr << "Reference has incorrect type" << std::endl;
98 throw 0;
100 return ref._retn();
103 //----------------------------------------------------------------
105 // Generic ostream inserter for exceptions. Inserts the exception
106 // name, if available, and the repository ID otherwise.
108 #if 0 // This inserter is not be needed for TAO.
110 static ostream &
111 operator<<(ostream & os, const CORBA::Exception & e)
113 CORBA::Any tmp;
114 tmp <<= e;
116 CORBA::TypeCode_var tc = tmp.type();
117 const char * p = tc->name();
118 if (*p != '\0')
119 os << p;
120 else
121 os << tc->id();
122 return os;
125 #endif
127 //----------------------------------------------------------------
129 // Show the details for a thermometer or thermostat.
131 // This inserter may or may not be needed for your ORB.
132 #if !defined (GEN_OSTREAM_OPS)
134 static std::ostream &
135 operator<<(std::ostream &os, CCS::Thermometer_ptr t)
137 // Check for nil.
138 if (CORBA::is_nil(t)) {
139 os << "Cannot show state for nil reference." << std::endl;
140 return os;
143 // Try to narrow and print what kind of device it is.
144 CCS::Thermostat_var tmstat = CCS::Thermostat::_narrow(t);
145 os << (CORBA::is_nil(tmstat.in()) ? "Thermometer:" : "Thermostat:")
146 << std::endl;
148 // Show attribute values.
149 CCS::ModelType_var model = t->model();
150 CCS::LocType_var location = t->location();
151 os << "\tAsset number: " << t->asset_num() << std::endl;
152 os << "\tModel : " << model.in() << std::endl;
153 os << "\tLocation : " << location.in() << std::endl;
154 os << "\tTemperature : " << t->temperature() << std::endl;
156 // If device is a thermostat, show nominal temperature.
157 if (!CORBA::is_nil(tmstat.in()))
158 os << "\tNominal temp: " << tmstat->get_nominal() << std::endl;
159 return os;
162 //----------------------------------------------------------------
164 // Show the information in a BtData struct.
166 static std::ostream &
167 operator<<(std::ostream &os, const CCS::Thermostat::BtData &btd)
169 os << "CCS::Thermostat::BtData details:" << std::endl;
170 os << "\trequested : " << btd.requested << std::endl;
171 os << "\tmin_permitted: " << btd.min_permitted << std::endl;
172 os << "\tmax_permitted: " << btd.max_permitted << std::endl;
173 os << "\terror_msg : " << btd.error_msg << std::endl;
174 return os;
177 //----------------------------------------------------------------
179 // Loop over the sequence of records in an EChange exception and
180 // show the details of each record.
182 static std::ostream &
183 operator<<(std::ostream &os, const CCS::Controller::EChange &ec)
185 for (CORBA::ULong i = 0; i < ec.errors.length(); i++) {
186 os << "Change failed:" << std::endl;
187 os << ec.errors[i].tmstat_ref.in(); // Overloaded <<
188 os << ec.errors[i].info << std::endl; // Overloaded <<
190 return os;
193 #endif
195 //----------------------------------------------------------------
197 // Change the temperature of a thermostat.
199 static void
200 set_temp(CCS::Thermostat_ptr tmstat, CCS::TempType new_temp)
202 if (CORBA::is_nil(tmstat)) // Don't call via nil reference
203 return;
205 CCS::AssetType anum = tmstat->asset_num();
206 try {
207 std::cout << "Setting thermostat " << anum
208 << " to " << new_temp << " degrees." << std::endl;
209 CCS::TempType old_nominal = tmstat->set_nominal(new_temp);
210 std::cout << "Old nominal temperature was: "
211 << old_nominal << std::endl;
212 std::cout << "New nominal temperature is: "
213 << tmstat->get_nominal() << std::endl;
214 } catch (const CCS::Thermostat::BadTemp &bt) {
215 std::cerr << "Setting of nominal temperature failed." << std::endl;
216 std::cerr << bt.details << std::endl; // Overloaded <<
220 //----------------------------------------------------------------
223 ACE_TMAIN(int argc, ACE_TCHAR *argv[])
225 CORBA::ULong i = 0;
227 try {
228 // Initialize the ORB
229 CORBA::ORB_var orb = CORBA::ORB_init(argc, argv);
231 // Check arguments
232 if (argc != 1) {
233 std::cerr << "Usage: client" << std::endl;
234 throw 0;
237 // Get reference to initial naming context.
238 CosNaming::NamingContext_var inc
239 = resolve_init<CosNaming::NamingContext>(orb.in(), "NameService");
241 // Look for controller in the Naming Service.
242 CosNaming::Name n;
243 n.length(2);
244 n[0].id = CORBA::string_dup("CCS");
245 n[1].id = CORBA::string_dup("Controller");
246 CCS::Controller_var ctrl;
247 try {
248 ctrl = resolve_name<CCS::Controller>(inc.in(), n);
249 } catch (const CosNaming::NamingContext::NotFound &) {
250 std::cerr << "No controller in Naming Service" << std::endl;
251 throw 0;
254 // Get list of devices
255 CCS::Controller::ThermometerSeq_var list = ctrl->list();
257 // Show number of devices.
258 CORBA::ULong len = list->length();
259 std::cout << "Controller has " << len << " device";
260 if (len != 1)
261 std::cout << "s";
262 std::cout << "." << std::endl;
264 CCS::Thermometer_var t = ctrl->create_thermometer(27, "Room 1");
265 CCS::Thermostat_var ts = ctrl->create_thermostat(28, "Room 2", 48);
266 CCS::Thermostat_var ts2 = ctrl->create_thermostat(30, "Room 3", 48);
267 CCS::Thermostat_var ts3 = ctrl->create_thermostat(32, "Room 3", 68);
268 CCS::Thermostat_var ts4 = ctrl->create_thermostat(34, "Room 3", 68);
269 CCS::Thermostat_var ts5 = ctrl->create_thermostat(36, "Room 3", 48);
270 std::cout << t->location() << std::endl;
271 std::cout << ts->location() << std::endl;
272 std::cout << ts2->location() << std::endl;
273 t->remove();
275 list = ctrl->list();
276 // Show details for each device.
277 for ( i = 0; i < list->length(); i++)
279 CCS::Thermometer_ptr ti = list[i];
280 std::cout << ti;
282 std::cout << std::endl;
284 // Change the location of first device in the list
285 CCS::AssetType anum = list[0u]->asset_num();
286 std::cout << "Changing location of device "
287 << anum << "." << std::endl;
288 list[0u]->location("Earth");
289 // Check that the location was updated
290 std::cout << "New details for device "
291 << anum << " are:" << std::endl;
292 CCS::Thermometer_ptr tx = list[0u];
293 std::cout << tx << std::endl;
295 // Find first thermostat in list.
296 CCS::Thermostat_var tmstat;
297 for ( i = 0;
298 i < list->length() && CORBA::is_nil(tmstat.in());
299 i++) {
300 tmstat = CCS::Thermostat::_narrow(list[i]);
303 // Check that we found a thermostat on the list.
304 if (CORBA::is_nil(tmstat.in())) {
305 std::cout << "No thermostat devices in list." << std::endl;
306 } else {
307 // Set temperature of thermostat to
308 // 50 degrees (should work).
309 set_temp(tmstat.inout(), 50);
310 std::cout << std::endl;
312 // Set temperature of thermostat to
313 // -10 degrees (should fail).
314 set_temp(tmstat.inout(), -10);
317 // Look for device in Rooms Earth and HAL. This must
318 // locate at least one device because we earlier changed
319 // the location of the first device to Room Earth.
320 std::cout << "Looking for devices in Earth and HAL." << std::endl;
321 CCS::Controller::SearchSeq ss;
322 ss.length(2);
323 ss[0].key.loc(CORBA::string_dup("Earth"));
324 ss[1].key.loc(CORBA::string_dup("HAL"));
325 ctrl->find(ss);
327 // Show the devices found in that room.
328 for ( i = 0; i < ss.length(); i++)
329 std::cout << ss[i].device.in(); // Overloaded <<
330 std::cout << std::endl;
332 // Increase the temperature of all thermostats
333 // by 40 degrees. First, make a new list (tss)
334 // containing only thermostats.
335 std::cout << "Increasing thermostats by 40 degrees." << std::endl;
336 CCS::Controller::ThermostatSeq tss;
337 for ( i = 0; i < list->length(); i++) {
338 tmstat = CCS::Thermostat::_narrow(list[i]);
339 if (CORBA::is_nil(tmstat.in()))
340 continue; // Skip thermometers
341 len = tss.length();
342 tss.length(len + 1);
343 tss[len] = tmstat;
346 // Try to change all thermostats.
347 try {
348 ctrl->change(tss, 40);
349 } catch (const CCS::Controller::EChange &ec) {
350 std::cerr << ec; // Overloaded <<
352 } catch (const CORBA::Exception & e) {
353 std::cerr << "Uncaught CORBA exception: "
354 << e
355 << std::endl;
356 return 1;
357 } catch (...) {
358 return 1;
360 return 0;