00001
00002
00003 #include "orbsvcs/Trader/Service_Type_Repository.h"
00004
00005 #include "ace/Lock_Adapter_T.h"
00006
00007
00008 ACE_RCSID (Trader,
00009 Service_Type_Repository,
00010 "$Id: Service_Type_Repository.cpp 77079 2007-02-12 19:41:31Z johnnyw $")
00011
00012
00013 TAO_BEGIN_VERSIONED_NAMESPACE_DECL
00014
00015 TAO_Service_Type_Repository::TAO_Service_Type_Repository (ACE_Lock* lock)
00016 : lock_ (lock)
00017 {
00018 this->incarnation_.low = 0;
00019 this->incarnation_.high = 0;
00020
00021
00022
00023 if (this->lock_ == 0)
00024 ACE_NEW (this->lock_,
00025 ACE_Lock_Adapter<ACE_Null_Mutex>);
00026 }
00027
00028 TAO_Service_Type_Repository::~TAO_Service_Type_Repository (void)
00029 {
00030 {
00031
00032 ACE_WRITE_GUARD (ACE_Lock, ace_mon, *this->lock_);
00033
00034 for (Service_Type_Map_Iterator service_map_iterator (this->type_map_);
00035 service_map_iterator.done () == 0;
00036 service_map_iterator++)
00037 {
00038 Type_Info *type_info = (*service_map_iterator).int_id_;
00039 delete type_info;
00040 }
00041 }
00042
00043 delete this->lock_;
00044 }
00045
00046 CosTradingRepos::ServiceTypeRepository::IncarnationNumber
00047 TAO_Service_Type_Repository::incarnation (void)
00048 {
00049 CosTradingRepos::ServiceTypeRepository::IncarnationNumber inc_num;
00050
00051 if (this->lock_->acquire_read () == -1)
00052 {
00053 inc_num = this->incarnation_;
00054 this->lock_->release ();
00055 }
00056 else
00057 {
00058 inc_num.high = 0;
00059 inc_num.low = 0;
00060 }
00061
00062 return inc_num;
00063 }
00064
00065
00066 CosTradingRepos::ServiceTypeRepository::IncarnationNumber
00067 TAO_Service_Type_Repository::
00068 add_type (const char *name,
00069 const char *if_name,
00070 const CosTradingRepos::ServiceTypeRepository::PropStructSeq &props,
00071 const CosTradingRepos::ServiceTypeRepository::ServiceTypeNameSeq &super_types)
00072 {
00073 Prop_Map prop_map;
00074 Service_Type_Map super_map;
00075
00076 ACE_WRITE_GUARD_THROW_EX (ACE_Lock, ace_mon, *this->lock_, CORBA::INTERNAL ());
00077
00078
00079 if (TAO_Trader_Base::is_valid_identifier_name (name) == 0)
00080 throw CosTrading::IllegalServiceType (name);
00081
00082
00083 CORBA::String_var type_name (name);
00084 if (this->type_map_.find (type_name) == 0)
00085 throw CosTradingRepos::ServiceTypeRepository::ServiceTypeExists ();
00086
00087
00088 this->validate_properties (prop_map,
00089 props);
00090
00091
00092 this->validate_supertypes (super_map,
00093 super_types);
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104 if (if_name == 0)
00105 throw CosTradingRepos::ServiceTypeRepository::InterfaceTypeMismatch ();
00106
00107
00108
00109
00110 this->validate_inheritance (prop_map,
00111 super_types);
00112
00113
00114
00115 this->update_type_map (name,
00116 if_name,
00117 props,
00118 super_types,
00119 prop_map,
00120 super_map);
00121
00122 CosTradingRepos::ServiceTypeRepository::IncarnationNumber return_value =
00123 this->incarnation_;
00124
00125
00126 this->incarnation_.low++;
00127
00128
00129 if (this->incarnation_.low == 0)
00130 this->incarnation_.high++;
00131
00132 return return_value;
00133 }
00134
00135 void
00136 TAO_Service_Type_Repository::remove_type (const char *name)
00137 {
00138 if (TAO_Trader_Base::is_valid_identifier_name (name) == 0)
00139 throw CosTrading::IllegalServiceType (name);
00140
00141 ACE_WRITE_GUARD_THROW_EX (ACE_Lock, ace_mon, *this->lock_, CORBA::INTERNAL ());
00142
00143
00144 Service_Type_Map::ENTRY* type_entry = 0; ;
00145 if (this->type_map_.find (name,
00146 type_entry) == -1)
00147 throw CosTrading::UnknownServiceType (name);
00148
00149
00150 Type_Info *type_info = type_entry->int_id_;
00151 if (type_info->has_subtypes_)
00152 throw CosTradingRepos::ServiceTypeRepository::HasSubTypes (name, "");
00153
00154
00155 this->type_map_.unbind (type_entry);
00156 delete type_info;
00157 }
00158
00159 CosTradingRepos::ServiceTypeRepository::ServiceTypeNameSeq *
00160 TAO_Service_Type_Repository::
00161 list_types (const CosTradingRepos::ServiceTypeRepository::SpecifiedServiceTypes &which_types)
00162 {
00163 ACE_READ_GUARD_THROW_EX (ACE_Lock, ace_mon, *this->lock_, CORBA::INTERNAL ());
00164
00165 CORBA::ULong i = 0;
00166 CORBA::ULong length = static_cast<CORBA::ULong> (this->type_map_.current_size ());
00167 CosTrading::ServiceTypeName *types =
00168 CosTradingRepos::ServiceTypeRepository::ServiceTypeNameSeq::allocbuf (length);
00169
00170 if (types == 0)
00171 return 0;
00172
00173 int all = which_types._d () == CosTradingRepos::ServiceTypeRepository::all;
00174
00175 CosTradingRepos::ServiceTypeRepository::IncarnationNumber num =
00176 which_types.incarnation ();
00177
00178 for (Service_Type_Map_Iterator itr (this->type_map_);
00179 itr.done () == 0;
00180 itr++)
00181 {
00182 Type_Info* type_info = (*itr).int_id_;
00183 const char* type_name = (*itr).ext_id_.in ();
00184
00185 if (all
00186 || num < type_info->type_struct_.incarnation)
00187 types[i++] = CORBA::string_dup (type_name);
00188 }
00189
00190 CosTradingRepos::ServiceTypeRepository::ServiceTypeNameSeq *tmp = 0;
00191
00192 ACE_NEW_RETURN (tmp,
00193 CosTradingRepos::ServiceTypeRepository::
00194 ServiceTypeNameSeq (length,
00195 i,
00196 types,
00197 1),
00198 0);
00199 return tmp;
00200 }
00201
00202 CosTradingRepos::ServiceTypeRepository::TypeStruct *
00203 TAO_Service_Type_Repository::
00204 describe_type (const char * name)
00205 {
00206 if (TAO_Trader_Base::is_valid_identifier_name (name) == 0)
00207 {
00208 throw CosTrading::IllegalServiceType (name);
00209 }
00210
00211 ACE_READ_GUARD_THROW_EX
00212 (ACE_Lock,
00213 ace_mon,
00214 *this->lock_,
00215 CORBA::INTERNAL ());
00216
00217
00218 CORBA::String_var type_name (name);
00219 Service_Type_Map::ENTRY *type_entry = 0;
00220 if (this->type_map_.find (type_name,
00221 type_entry) == -1)
00222 throw CosTrading::UnknownServiceType (name);
00223
00224
00225 CosTradingRepos::ServiceTypeRepository::TypeStruct *descr = 0;
00226 ACE_NEW_RETURN (descr,
00227 CosTradingRepos::ServiceTypeRepository::TypeStruct,
00228 0);
00229 CosTradingRepos::ServiceTypeRepository::TypeStruct &s =
00230 type_entry->int_id_->type_struct_;
00231
00232 descr->if_name = s.if_name;
00233 descr->masked = s.masked;
00234 descr->incarnation = s.incarnation;
00235 descr->super_types = s.super_types;
00236 descr->props = s.props;
00237
00238
00239
00240
00241
00242
00243 return descr;
00244 }
00245
00246 CosTradingRepos::ServiceTypeRepository::TypeStruct *
00247 TAO_Service_Type_Repository::
00248 fully_describe_type (const char *name)
00249 {
00250 if (TAO_Trader_Base::is_valid_identifier_name (name) == 0)
00251 throw CosTrading::IllegalServiceType (name);
00252
00253 ACE_READ_GUARD_THROW_EX (ACE_Lock, ace_mon, *this->lock_, CORBA::INTERNAL ());
00254
00255
00256 CORBA::String_var type_name (name);
00257 Service_Type_Map::ENTRY *type_entry = 0;
00258 if (this->type_map_.find (type_name,
00259 type_entry) == -1)
00260 throw CosTrading::UnknownServiceType (name);
00261
00262
00263 CosTradingRepos::ServiceTypeRepository::TypeStruct *descr = 0;
00264 ACE_NEW_RETURN (descr,
00265 CosTradingRepos::ServiceTypeRepository::TypeStruct,
00266 0);
00267 CosTradingRepos::ServiceTypeRepository::TypeStruct &s =
00268 type_entry->int_id_->type_struct_;
00269
00270
00271
00272 this->fully_describe_type_i (s,
00273 descr->props,
00274 descr->super_types);
00275
00276
00277
00278 descr->if_name = s.if_name;
00279 descr->masked = s.masked;
00280 descr->incarnation = s.incarnation;
00281
00282 return descr;
00283 }
00284
00285 void
00286 TAO_Service_Type_Repository::
00287 mask_type (const char *name)
00288 {
00289 if (TAO_Trader_Base::is_valid_identifier_name (name) == 0)
00290 throw CosTrading::IllegalServiceType (name);
00291
00292 ACE_WRITE_GUARD_THROW_EX (ACE_Lock, ace_mon, *this->lock_, CORBA::INTERNAL ());
00293
00294
00295 CORBA::String_var type_name (name);
00296 Service_Type_Map::ENTRY *type_entry = 0;
00297 if (this->type_map_.find (type_name,
00298 type_entry) != -1)
00299 throw CosTrading::UnknownServiceType (name);
00300
00301
00302 CORBA::Boolean &mask =
00303 type_entry->int_id_->type_struct_.masked;
00304
00305 if (mask == 1)
00306 throw CosTradingRepos::ServiceTypeRepository::AlreadyMasked (name);
00307 else
00308 mask = 1;
00309 }
00310
00311 void
00312 TAO_Service_Type_Repository::unmask_type (const char *name)
00313 {
00314 if (TAO_Trader_Base::is_valid_identifier_name (name) == 0)
00315 throw CosTrading::IllegalServiceType (name);
00316
00317 ACE_WRITE_GUARD_THROW_EX (ACE_Lock, ace_mon, *this->lock_, CORBA::INTERNAL ());
00318
00319
00320 CORBA::String_var type_name (name);
00321 Service_Type_Map::ENTRY *type_entry = 0;
00322 if (this->type_map_.find (type_name,
00323 type_entry) != -1)
00324 throw CosTrading::UnknownServiceType (name);
00325
00326
00327 CORBA::Boolean &mask = type_entry->int_id_->type_struct_.masked;
00328
00329 if (mask == 0)
00330 throw CosTradingRepos::ServiceTypeRepository::NotMasked (name);
00331 else
00332 mask = 0;
00333 }
00334
00335 void
00336 TAO_Service_Type_Repository::
00337 fully_describe_type_i (const CosTradingRepos::ServiceTypeRepository::TypeStruct &type_struct,
00338 CosTradingRepos::ServiceTypeRepository::PropStructSeq &props,
00339 CosTradingRepos::ServiceTypeRepository::ServiceTypeNameSeq &super_types)
00340 {
00341 TAO_String_Queue service_type_queue;
00342 this->collect_inheritance_hierarchy (type_struct,
00343 service_type_queue);
00344
00345
00346 CORBA::ULong num_props = 0;
00347 CORBA::ULong num_types = static_cast<CORBA::ULong> (service_type_queue.size ());
00348
00349 TAO_String_Queue::ITERATOR iterator (service_type_queue);
00350
00351 for (;
00352 iterator.done () == 0;
00353 iterator.advance ())
00354 {
00355 char **next_type_name = 0;
00356 Service_Type_Map::ENTRY *type_entry = 0;
00357
00358 iterator.next (next_type_name);
00359 CORBA::String_var hash_key (const_cast<const char *> (*next_type_name));
00360 this->type_map_.find (hash_key,
00361 type_entry);
00362
00363 CosTradingRepos::ServiceTypeRepository::TypeStruct &tstruct =
00364 type_entry->int_id_->type_struct_;
00365 num_props += tstruct.props.length ();
00366 }
00367
00368 num_props += type_struct.props.length ();
00369 props.length (num_props);
00370 super_types.length (num_types);
00371
00372
00373 int i = 0;
00374 CORBA::ULong prop_index = 0;
00375 CORBA::ULong type_index = 0;
00376
00377 for (i = type_struct.props.length () - 1;
00378 i >= 0;
00379 i--)
00380 props[prop_index++] = type_struct.props[i];
00381
00382 for (iterator.first ();
00383 iterator.done () == 0;
00384 iterator.advance ())
00385 {
00386 char **next_type_name = 0;
00387 Service_Type_Map::ENTRY *type_entry = 0;
00388
00389 iterator.next (next_type_name);
00390 CORBA::String_var hash_key (const_cast<const char *> (*next_type_name));
00391 this->type_map_.find (hash_key,
00392 type_entry);
00393
00394
00395 if (type_entry != 0)
00396 {
00397 CosTradingRepos::ServiceTypeRepository::TypeStruct& tstruct =
00398 type_entry->int_id_->type_struct_;
00399
00400 for (i = tstruct.props.length () - 1;
00401 i >= 0;
00402 i--)
00403 props[prop_index++] = tstruct.props[i];
00404
00405 super_types[type_index++] = hash_key.in ();
00406 }
00407 }
00408 }
00409
00410 void
00411 TAO_Service_Type_Repository::
00412 collect_inheritance_hierarchy (const CosTradingRepos::ServiceTypeRepository::TypeStruct &type_struct,
00413 TAO_String_Queue &target)
00414 {
00415
00416 for (int i = type_struct.super_types.length () - 1;
00417 i >= 0;
00418 i--)
00419 {
00420 Service_Type_Map::ENTRY *next_type_entry = 0;
00421 CORBA::String_var next_type_name (type_struct.super_types[i]);
00422
00423 if (this->type_map_.find (next_type_name, next_type_entry) != -1)
00424 {
00425 CosTradingRepos::ServiceTypeRepository::TypeStruct &next_type_struct =
00426 next_type_entry->int_id_->type_struct_;
00427
00428 const char *type_name =
00429 type_struct.super_types[i];
00430 target.enqueue_tail (const_cast<char *> (type_name));
00431
00432 this->collect_inheritance_hierarchy (next_type_struct,
00433 target);
00434 }
00435 }
00436 }
00437
00438 void
00439 TAO_Service_Type_Repository::
00440 validate_properties (Prop_Map &prop_map,
00441 const CosTradingRepos::ServiceTypeRepository::PropStructSeq &props)
00442 {
00443 for (CORBA::ULong i = 0;
00444 i < props.length ();
00445 i++)
00446 {
00447 const char *n = props[i].name;
00448 if (TAO_Trader_Base::is_valid_property_name (n) == 0)
00449 throw CosTrading::IllegalPropertyName (n);
00450 else
00451 {
00452 CORBA::String_var prop_name (n);
00453 CosTradingRepos::ServiceTypeRepository::PropStruct *prop_val =
00454 const_cast<CosTradingRepos::ServiceTypeRepository::PropStruct *> (&props[i]);
00455
00456 if (prop_map.bind (prop_name,
00457 prop_val) == 1)
00458 throw CosTrading::DuplicatePropertyName (n);
00459 }
00460 }
00461 }
00462
00463 void
00464 TAO_Service_Type_Repository::
00465 validate_supertypes (Service_Type_Map &super_map,
00466 const CosTradingRepos::ServiceTypeRepository::ServiceTypeNameSeq &super_types)
00467 {
00468 for (CORBA::ULong i = 0;
00469 i < super_types.length ();
00470 i++)
00471 {
00472 const char *type =
00473 super_types[i];
00474
00475 if (TAO_Trader_Base::is_valid_identifier_name (type) == 0)
00476 throw CosTrading::IllegalServiceType (type);
00477 else
00478 {
00479 CORBA::String_var hash_type (type);
00480 Service_Type_Map::ENTRY *type_entry = 0;
00481
00482 if (this->type_map_.find (hash_type,
00483 type_entry) == -1)
00484 throw CosTrading::UnknownServiceType (type);
00485 else
00486 {
00487 if (super_map.bind (hash_type,
00488 type_entry->int_id_) == 1)
00489 throw CosTradingRepos::ServiceTypeRepository::DuplicateServiceTypeName (
00490 type);
00491 }
00492 }
00493 }
00494 }
00495
00496 void
00497 TAO_Service_Type_Repository::
00498 validate_inheritance (Prop_Map &prop_map,
00499 const CosTradingRepos::ServiceTypeRepository::ServiceTypeNameSeq &super_types)
00500 {
00501 CORBA::ULong num_super_types = super_types.length ();
00502
00503 for (CORBA::ULong i = 0;
00504 i < num_super_types;
00505 i++)
00506 {
00507 Service_Type_Map::ENTRY *super_type_entry = 0;
00508 CORBA::String_var super_type (super_types[i]);
00509 CosTradingRepos::ServiceTypeRepository::ServiceTypeNameSeq place_holder;
00510 CosTradingRepos::ServiceTypeRepository::PropStructSeq super_props;
00511
00512 this->type_map_.find (super_type, super_type_entry);
00513
00514
00515 if (super_type_entry != 0)
00516 this->fully_describe_type_i (super_type_entry->int_id_->type_struct_,
00517 super_props,
00518 place_holder);
00519 else
00520 continue;
00521
00522 CORBA::ULong num_props = super_props.length ();
00523
00524 for (CORBA::ULong j = 0;
00525 j < num_props;
00526 j++)
00527 {
00528 Prop_Map::ENTRY *existing_prop = 0;
00529 CORBA::String_var prop_name (super_props[j].name);
00530
00531 if (prop_map.bind (prop_name,
00532 &super_props[j],
00533 existing_prop) == 1)
00534 {
00535
00536
00537
00538 const CosTradingRepos::ServiceTypeRepository::PropStruct &property_in_map =
00539 *existing_prop->int_id_;
00540
00541 CORBA::TypeCode_ptr prop_type = property_in_map.value_type.in ();
00542 int compare = 0;
00543 try
00544 {
00545 compare =
00546 super_props[j].value_type->equal (prop_type);
00547 }
00548 catch (const CORBA::Exception&)
00549 {
00550 throw CosTradingRepos::ServiceTypeRepository::ValueTypeRedefinition(
00551 super_props[j].name,
00552 super_props[j],
00553 property_in_map.name,
00554 property_in_map);
00555 }
00556
00557 if (compare == 0
00558 || super_props[j].mode > property_in_map.mode)
00559 throw CosTradingRepos::ServiceTypeRepository::ValueTypeRedefinition(
00560 super_props[j].name,
00561 super_props[j],
00562 property_in_map.name,
00563 property_in_map);
00564 }
00565 }
00566 }
00567 }
00568
00569 void
00570 TAO_Service_Type_Repository::
00571 update_type_map (const char *name,
00572 const char *if_name,
00573 const CosTradingRepos::ServiceTypeRepository::PropStructSeq &props,
00574 const CosTradingRepos::ServiceTypeRepository::ServiceTypeNameSeq &super_types,
00575 Prop_Map &,
00576 Service_Type_Map &super_map)
00577 {
00578
00579
00580
00581 for (Service_Type_Map_Iterator super_map_iterator (super_map);
00582 super_map_iterator.done () == 0;
00583 super_map_iterator++)
00584 {
00585 Type_Info *super_type_info =
00586 (*super_map_iterator).int_id_;
00587 super_type_info->has_subtypes_ = 0;
00588 }
00589
00590
00591
00592 Type_Info *type = 0;
00593 ACE_NEW (type,
00594 Type_Info);
00595
00596 type->type_struct_.props = props;
00597 type->type_struct_.if_name = if_name;
00598 type->type_struct_.super_types = super_types;
00599 type->type_struct_.incarnation = this->incarnation_;
00600 type->type_struct_.masked = 0;
00601 type->has_subtypes_ = 0;
00602
00603
00604
00605
00606
00607
00608
00609
00610
00611
00612
00613
00614
00615
00616 CORBA::String_var type_name (name);
00617 this->type_map_.bind (type_name, type);
00618 }
00619
00620 TAO_END_VERSIONED_NAMESPACE_DECL