00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 #include "Container.h"
00024
00025 #include "Contained.h"
00026 #include "Repository.h"
00027 #include "ModuleDef.h"
00028
00029 #include "ConstantDef.h"
00030 #include "StructDef.h"
00031 #include "UnionDef.h"
00032 #include "EnumDef.h"
00033 #include "AliasDef.h"
00034 #include "InterfaceDef.h"
00035 #include "ExceptionDef.h"
00036
00037 #include "PersistNode.h"
00038 #include "Creche.h"
00039
00040 #include <string.h>
00041 #include <algorithm>
00042
00043 namespace Omniifr {
00044
00045 Contained_ptr Container_impl::lookup(const char* search_name)
00046 {
00047 Contained_impl* result =lookupServant(search_name,true);
00048 if(result)
00049 return result->_this();
00050 else
00051 return Contained::_nil();
00052 }
00053
00054
00058 ContainedSeq* Container_impl::contents(
00059 DefinitionKind limit_type,
00060 CORBA::Boolean exclude_inherited
00061 )
00062 {
00063 ContainedSeq_var result = new ContainedSeq();
00064 ULong resultLength =0;
00065
00066 for(list<Contained_impl*>::iterator it =_contents.begin();
00067 it!=_contents.end();
00068 ++it)
00069 {
00070 if(limit_type==dk_all || limit_type==(*it)->def_kind())
00071 {
00072 result->length(resultLength+1);
00073 result[resultLength]=(*it)->_this();
00074 ++resultLength;
00075 }
00076 }
00077 return result._retn();
00078 }
00079
00083 ContainedSeq* Container_impl::lookup_name(
00084 const char* search_name,
00085 CORBA::Long levels_to_search,
00086 DefinitionKind limit_type,
00087 CORBA::Boolean exclude_inherited
00088 )
00089 {
00090 ContainedSeq_var result =new ContainedSeq();
00091 ULong resultLength =0;
00092 Long subLevels =levels_to_search<0? levels_to_search : levels_to_search-1;
00093 EqualName equalName(search_name,true);
00094
00095
00096 ContainedSeq_var contents =this->contents(limit_type,exclude_inherited);
00097 for(ULong i=0; i<contents->length(); ++i)
00098 {
00099 if(equalName(contents[i]) &&
00100 limit_type==dk_all || limit_type==contents[i]->def_kind())
00101 {
00102 result->length(resultLength+1);
00103 result[resultLength]=contents[i];
00104 ++resultLength;
00105 }
00106 }
00107
00108
00109 if(subLevels!=0)
00110 {
00111 for(list<Contained_impl*>::iterator it =_contents.begin();
00112 it!=_contents.end();
00113 ++it)
00114 {
00115 Container_impl* subContainer =dynamic_cast<Container_impl*>(*it);
00116 if(subContainer)
00117 {
00118 ContainedSeq_var subResult =subContainer->
00119 lookup_name(search_name,subLevels,limit_type,exclude_inherited);
00120 result->length( resultLength+subResult->length() );
00121 for(ULong j=0; j<subResult->length(); ++j)
00122 result[resultLength++]=subResult[j]._retn();
00123 }
00124 }
00125 }
00126 return result._retn();
00127 }
00128
00129 CORBA::Container::DescriptionSeq* Container_impl::describe_contents(
00130 DefinitionKind limit_type,
00131 Boolean exclude_inherited,
00132 Long max_returned_objs
00133 )
00134 {
00135 ContainedSeq_var containedseq =contents(limit_type,exclude_inherited);
00136
00137 ULong numObjectsToReturn =containedseq->length();
00138 if(max_returned_objs>=Long(numObjectsToReturn))
00139 numObjectsToReturn=max_returned_objs;
00140
00141 CORBA::Container::DescriptionSeq_var result =
00142 new CORBA::Container::DescriptionSeq();
00143 result->length(numObjectsToReturn);
00144
00145 for(ULong i=0; i<numObjectsToReturn; ++i)
00146 {
00147 CORBA::Contained::Description_var iDescription =containedseq[i]->describe();
00148 result[i].contained_object=containedseq[i];
00149 result[i].kind =iDescription->kind;
00150 result[i].value =iDescription->value;
00151 }
00152 return result._retn();
00153 }
00154
00155 ModuleDef_ptr Container_impl::create_module(
00156 const char* id, const char* name, const char* version
00157 )
00158 {
00159 DB(5,"Container::create_module("<<id<<","<<name<<","<<version<<")")
00160 checkReadonly();
00161 Creche<ModuleDef_impl> newmodule(new ModuleDef_impl());
00162 newmodule->init(id,name,version,this);
00163 return newmodule.release()->_this();
00164 }
00165
00166 ConstantDef_ptr Container_impl::create_constant(
00167 const char* id, const char* name, const char* version,
00168 IDLType_ptr type,
00169 const Any& value
00170 )
00171 {
00172 DB(5,"Container::create_constant("<<id<<","<<name<<","<<version<<",...)")
00173 checkReadonly();
00174 Creche<ConstantDef_impl> newconstant(new ConstantDef_impl());
00175 newconstant->init(id,name,version,this);
00176
00177 newconstant->type_def(type);
00178 newconstant->value(value);
00179 return newconstant.release()->_this();
00180 }
00181
00182 StructDef_ptr Container_impl::create_struct(
00183 const char* id, const char* name, const char* version,
00184 const StructMemberSeq& members
00185 )
00186 {
00187 DB(5,"Container::create_struct("<<id<<","<<name<<","<<version<<",...)")
00188 checkReadonly();
00189 Creche<StructDef_impl> newstruct(new StructDef_impl());
00190 newstruct->init(id,name,version,this);
00191 newstruct->members(members);
00192 return newstruct.release()->_this();
00193 }
00194
00195 UnionDef_ptr Container_impl::create_union(
00196 const char* id, const char* name, const char* version,
00197 IDLType_ptr discriminator_type,
00198 const UnionMemberSeq& members
00199 )
00200 {
00201 DB(5,"Container::create_union("<<id<<","<<name<<","<<version<<",...)")
00202 checkReadonly();
00203 Creche<UnionDef_impl> newunion(new UnionDef_impl());
00204 newunion->init(id,name,version,this);
00205
00206 newunion->discriminator_type_def(discriminator_type);
00207 newunion->members(members);
00208 return newunion.release()->_this();
00209 }
00210
00211 EnumDef_ptr Container_impl::create_enum(
00212 const char* id, const char* name, const char* version,
00213 const EnumMemberSeq& members
00214 )
00215 {
00216 DB(5,"Container::create_enum("<<id<<","<<name<<","<<version<<",...)")
00217 checkReadonly();
00218 Creche<EnumDef_impl> newenum(new EnumDef_impl());
00219 newenum->init(id,name,version,this);
00220 newenum->members(members);
00221 return newenum.release()->_this();
00222 }
00223
00224 AliasDef_ptr Container_impl::create_alias(
00225 const char* id, const char* name, const char* version,
00226 IDLType_ptr original_type
00227 )
00228 {
00229 DB(5,"Container::create_alias("<<id<<","<<name<<","<<version<<",...)")
00230 checkReadonly();
00231 Creche<AliasDef_impl> newalias(new AliasDef_impl());
00232 newalias->init(id,name,version,this);
00233 newalias->original_type_def(original_type);
00234 return newalias.release()->_this();
00235 }
00236
00237 InterfaceDef_ptr Container_impl::create_interface(
00238 const char* id, const char* name, const char* version,
00239 const InterfaceDefSeq& base_interfaces
00240 )
00241 {
00242 DB(5,"Container::create_interface("<<id<<","<<name<<","<<version<<",...)")
00243 checkReadonly();
00244 Creche<InterfaceDef_impl> newinterface(new InterfaceDef_impl());
00245 newinterface->init(id,name,version,this);
00246 newinterface->base_interfaces(base_interfaces);
00247 return newinterface.release()->_this();
00248 }
00249
00250 ExceptionDef_ptr Container_impl::create_exception(
00251 const char* id, const char* name, const char* version,
00252 const StructMemberSeq& members
00253 )
00254 {
00255 DB(5,"Container::create_exception("<<id<<","<<name<<","<<version<<",...)")
00256 checkReadonly();
00257 Creche<ExceptionDef_impl> newexception(new ExceptionDef_impl());
00258 newexception->init(id,name,version,this);
00259 newexception->members(members);
00260 return newexception.release()->_this();
00261 }
00262
00263 ValueDef_ptr Container_impl::create_value(
00264 const char* id, const char* name, const char* version,
00265 Boolean is_custom,
00266 Boolean is_abstract,
00267 ValueDef_ptr base_value,
00268 Boolean is_truncatable,
00269 const ValueDefSeq& abstract_base_values,
00270 const InterfaceDefSeq& supported_interfaces,
00271 const InitializerSeq& initializers
00272 )
00273 {
00274 DB(5,"Container::create_value("<<id<<","<<name<<","<<version<<",...)")
00275 checkReadonly();
00276
00277 return ValueDef::_nil();
00278 }
00279
00280 ValueBoxDef_ptr Container_impl::create_value_box(
00281 const char* id, const char* name, const char* version,
00282 IDLType_ptr original_type_def
00283 )
00284 {
00285 DB(5,"Container::create_value_box("<<id<<","<<name<<","<<version<<",...)")
00286 checkReadonly();
00287
00288 return ValueBoxDef::_nil();
00289 }
00290
00291 NativeDef_ptr Container_impl::create_native(
00292 const char* id, const char* name, const char* version
00293 )
00294 {
00295 DB(5,"Container::create_native("<<id<<","<<name<<","<<version<<",...)")
00296 checkReadonly();
00297
00298 return NativeDef::_nil();
00299 }
00300
00301 AbstractInterfaceDef_ptr Container_impl:: create_abstract_interface(
00302 const char* id, const char* name, const char* version,
00303 const AbstractInterfaceDefSeq& base_interfaces
00304 )
00305 {
00306 DB(5,"Container::create_abstract_interface("<<id<<","<<name<<","<<version<<",...)")
00307 checkReadonly();
00308
00309 return AbstractInterfaceDef::_nil();
00310 }
00311
00312
00313
00314
00315
00316 void Container_impl::dependentObjectSet(set<const IRObject_impl*>& result) const
00317 {
00318 IRObject_impl::dependentObjectSet(result);
00319
00320 for(list<Contained_impl*>::const_iterator i=_contents.begin();
00321 i!=_contents.end();
00322 ++i)
00323 {
00324 (**i).dependentObjectSet(result);
00325 }
00326 }
00327
00328 void Container_impl::containedObjectSet(set<const IRObject_impl*>& result) const
00329 {
00330 IRObject_impl::containedObjectSet(result);
00331
00332 for(list<Contained_impl*>::const_iterator i=_contents.begin();
00333 i!=_contents.end();
00334 ++i)
00335 {
00336 (**i).containedObjectSet(result);
00337 }
00338 }
00339
00340 void Container_impl::recreate(
00341 PersistNode* node,
00342 map<IRObject_impl*,PersistNode*>& todo)
00343 {
00344 if(!node)
00345 {
00346 DB(1,"Container_impl::recreate(): NULL child node encountered.")
00347 return;
00348 }
00349
00350 for(map<string,PersistNode*>::const_iterator i =node->_child.begin();
00351 i!=node->_child.end();
00352 ++i)
00353 {
00354 const string iOid =i->second->attrString("oid");
00355 const string iId =i->second->attrString("id");
00356 const string iVersion =i->second->attrString("version");
00357 const string iClass =i->second->attrString("class");
00358 const int iIndex =i->second->attrLong("index");
00359 if(iOid.empty() || iId.empty() || iVersion.empty() || iClass.empty())
00360 {
00361 DB(1,"Container_impl::recreate(): expected 'Contained' type child node.")
00362 i->second->output(cerr,i->first);
00363 continue;
00364 }
00365
00366 if("ModuleDef"==iClass)
00367 {
00368 Creche<ModuleDef_impl> servant(new ModuleDef_impl());
00369 servant->init(iId.c_str(),i->first.c_str(),iVersion.c_str(),this,iIndex);
00370 servant->recreate(i->second,todo);
00371 servant.release(iOid.c_str());
00372 }
00373 else if("ConstantDef"==iClass)
00374 {
00375 Creche<ConstantDef_impl> servant(new ConstantDef_impl());
00376 servant->init(iId.c_str(),i->first.c_str(),iVersion.c_str(),this,iIndex);
00377 todo[servant.get()]=i->second;
00378 servant.release(iOid.c_str());
00379 }
00380 else if("StructDef"==iClass)
00381 {
00382 Creche<StructDef_impl> servant(new StructDef_impl());
00383 servant->init(iId.c_str(),i->first.c_str(),iVersion.c_str(),this,iIndex);
00384 servant->recreate(i->second,todo);
00385 todo[servant.get()]=i->second;
00386 servant.release(iOid.c_str());
00387 }
00388 else if("UnionDef"==iClass)
00389 {
00390 Creche<UnionDef_impl> servant(new UnionDef_impl());
00391 servant->init(iId.c_str(),i->first.c_str(),iVersion.c_str(),this,iIndex);
00392 servant->recreate(i->second,todo);
00393 todo[servant.get()]=i->second;
00394 servant.release(iOid.c_str());
00395 }
00396 else if("EnumDef"==iClass)
00397 {
00398 Creche<EnumDef_impl> servant(new EnumDef_impl());
00399 servant->init(iId.c_str(),i->first.c_str(),iVersion.c_str(),this,iIndex);
00400 todo[servant.get()]=i->second;
00401 servant.release(iOid.c_str());
00402 }
00403 else if("AliasDef"==iClass)
00404 {
00405 Creche<AliasDef_impl> servant(new AliasDef_impl());
00406 servant->init(iId.c_str(),i->first.c_str(),iVersion.c_str(),this,iIndex);
00407 todo[servant.get()]=i->second;
00408 servant.release(iOid.c_str());
00409 }
00410 else if("InterfaceDef"==iClass)
00411 {
00412 Creche<InterfaceDef_impl> servant(new InterfaceDef_impl());
00413 servant->init(iId.c_str(),i->first.c_str(),iVersion.c_str(),this,iIndex);
00414 servant->recreate(i->second,todo);
00415 todo[servant.get()]=i->second;
00416 servant.release(iOid.c_str());
00417 }
00418 else if("ExceptionDef"==iClass)
00419 {
00420 Creche<ExceptionDef_impl> servant(new ExceptionDef_impl());
00421 servant->init(iId.c_str(),i->first.c_str(),iVersion.c_str(),this,iIndex);
00422 servant->recreate(i->second,todo);
00423 todo[servant.get()]=i->second;
00424 servant.release(iOid.c_str());
00425 }
00426 else if("AttributeDef"!=iClass && "OperationDef"!=iClass)
00427 {
00428 DB(1,"Container_impl::recreate(): "
00429 "unexpected child class "<<iClass.c_str())
00430 }
00431 }
00432 }
00433
00434 void Container_impl::outputContents(ostream &os) const
00435 {
00436 for(list<Contained_impl*>::const_iterator i=_contents.begin();
00437 i!=_contents.end();
00438 ++i)
00439 {
00440 (**i).output(os);
00441 }
00442 }
00443
00444 Container_impl::Container_impl() : _contents()
00445 {
00446 _contents.clear();
00447 }
00448
00449 void Container_impl::uncheckedDestroy()
00450 {
00451 for(list<Contained_impl*>::const_iterator i=_contents.begin();
00452 i!=_contents.end();
00453 ++i)
00454 {
00455 (**i).uncheckedDestroy();
00456 }
00457 _contents.clear();
00458 }
00459
00460 Contained_impl* Container_impl::lookupServant(
00461 const char* searchName,
00462 bool matchCase
00463 )
00464 {
00465 assert(searchName);
00466 if(!searchName[0])
00467 return NULL;
00468
00469
00470 const char* offset =strstr(searchName,"::");
00471 string first(searchName,offset?offset-searchName:strlen(searchName));
00472 string theRest(offset?offset+2:"");
00473
00474 Contained_impl* result =NULL;
00475
00476 if(first.empty())
00477 {
00478 result=Repository_impl::inst().lookupServant(theRest.c_str(),matchCase);
00479 }
00480 else
00481 {
00482 list<Contained_impl*>::iterator pos =
00483 find_if(
00484 _contents.begin(),
00485 _contents.end(),
00486 EqualName(first.c_str(),matchCase)
00487 );
00488 if(pos!=_contents.end())
00489 {
00490 if(theRest.empty())
00491 {
00492 result=*pos;
00493 }
00494 else
00495 {
00496 Container_impl* container =dynamic_cast<Container_impl*>(*pos);
00497 if(container)
00498 result=container->lookupServant(theRest.c_str(),matchCase);
00499 }
00500 }
00501 }
00502 return result;
00503 }
00504
00505 void Container_impl::addContained(Contained_impl* contained)
00506 {
00507
00508
00509
00510
00511
00512 this->_add_ref();
00513 try
00514 {
00515
00516 assert(find_if(_contents.begin(),_contents.end(),
00517 bind2nd(equal_to<Contained_impl*>(),contained))
00518 ==_contents.end()
00519 );
00520
00521 if(!canContain(contained->def_kind()))
00522 throw CORBA::BAD_PARAM(
00523 IFELSE_OMNIORB4(omni::BAD_PARAM_TargetIsInvalidContainer,4),
00524 CORBA::COMPLETED_NO
00525 );
00526
00527 if(contained->_index > 0)
00528 {
00529
00530 list<Contained_impl*>::iterator pos=_contents.begin();
00531 while(pos!=_contents.end() && (*pos)->_index < contained->_index)
00532 ++pos;
00533 _contents.insert(pos,contained);
00534 }
00535 else
00536 {
00537
00538 contained->_index=(_contents.empty()? 1: 1+_contents.back()->_index);
00539 _contents.push_back(contained);
00540 }
00541 }
00542 catch(...)
00543 {
00544 this->_remove_ref();
00545 throw;
00546 }
00547 }
00548
00549 void Container_impl::removeContained(Contained_impl* contained)
00550 {
00551 list<Contained_impl*>::iterator pos =
00552 find_if(_contents.begin(),_contents.end(),
00553 bind2nd(equal_to<Contained_impl*>(),contained));
00554 assert(pos!=_contents.end());
00555 _contents.erase(pos);
00556 this->_remove_ref();
00557 }
00558
00559 bool Container_impl::EqualName::operator()(Contained_impl* c)
00560 {
00561 return test(c->name());
00562 }
00563
00564 }