00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 #include "Repository.h"
00024
00025 #include "Contained.h"
00026 #include "TypedefDef.h"
00027
00028 #include "PrimitiveDef.h"
00029 #include "StringDef.h"
00030 #include "WstringDef.h"
00031 #include "SequenceDef.h"
00032 #include "ArrayDef.h"
00033 #include "FixedDef.h"
00034 #include "Persist.h"
00035 #include "PersistNode.h"
00036
00037 #include "Creche.h"
00038 #include <string.h>
00039
00040 namespace Omniifr {
00041
00046 template<class T>
00047 typename T::_ptr_type lookupTc(
00048 Repository_impl& repository,
00049 TypeCode_ptr tc,
00050 const char*& id,
00051 const char*& name
00052 )
00053 {
00054
00055
00056
00057 id =tc->id();
00058 name =tc->name();
00059
00060
00061 Contained_var contained =repository.lookup_id(id);
00062 typename T::_var_type result =T::_nil();
00063 if(!CORBA::is_nil(contained))
00064 {
00065 result=T::_narrow(contained.in());
00066 if(CORBA::is_nil(result))
00067 {
00068 DB(1,id<<" is in the repository, but TCKind does not match.")
00069 }
00070 }
00071 return result._retn();
00072 }
00073
00074
00075
00076
00077
00078
00079
00080 Repository_impl Repository_impl::_inst;
00081
00082
00083 Contained_ptr Repository_impl::lookup_id(const char* search_id)
00084 {
00085 DB(7,"lookup_id(\""<<search_id<<"\")")
00086 if(!( 0==strcmp(search_id,"IDL:omg.org/CORBA/Object:1.0") ||
00087 0==strcmp(search_id,"IDL:omg.org/CORBA/ValueBase:1.0") ))
00088 {
00089 Contained_impl* result =findId(search_id);
00090 if(result)
00091 return result->_this();
00092 }
00093 return Contained::_nil();
00094 }
00095
00096
00097 TypeCode_ptr Repository_impl::get_canonical_typecode(TypeCode_ptr tc)
00098 {
00099 TypeCode_var result =TypeCode::_nil();
00100
00101 const char* id;
00102 const char* name;
00103
00104 switch(tc->kind())
00105 {
00106
00107 case tk_objref:
00108 {
00109 InterfaceDef_var interfaceDef=lookupTc<InterfaceDef>(*this,tc,id,name);
00110 if(CORBA::is_nil(interfaceDef))
00111 result=TypeCode::_duplicate(tc);
00112 else
00113 result=interfaceDef->type();
00114 }
00115 break;
00116
00117 case tk_struct:
00118 {
00119 StructDef_var structDef=lookupTc<StructDef>(*this,tc,id,name);
00120 if(CORBA::is_nil(structDef))
00121 {
00122 StructMemberSeq ms;
00123 ms.length(tc->member_count());
00124 for(ULong i=0; i<ms.length(); ++i)
00125 {
00126 TypeCode_var memberType=tc->member_type(i);
00127 ms[i].name =CORBA::string_dup(tc->member_name(i));
00128 ms[i].type =get_canonical_typecode(memberType.in());
00129 ms[i].type_def=IDLType::_nil();
00130 }
00131 result=_orb->create_struct_tc(id,name,ms);
00132 }
00133 else
00134 {
00135 result=structDef->type();
00136 }
00137 }
00138 break;
00139
00140 case tk_union:
00141 {
00142 UnionDef_var unionDef=lookupTc<UnionDef>(*this,tc,id,name);
00143 if(CORBA::is_nil(unionDef))
00144 {
00145 UnionMemberSeq ms;
00146 ms.length(tc->member_count());
00147 for(ULong i=0; i<ms.length(); ++i)
00148 {
00149 TypeCode_var memberType =tc->member_type(i);
00150 Any_var memberLabel =tc->member_label(i);
00151 ms[i].name =CORBA::string_dup(tc->member_name(i));
00152 ms[i].label =memberLabel.in();
00153 ms[i].type =get_canonical_typecode(memberType.in());
00154 ms[i].type_def=IDLType::_nil();
00155 }
00156 TypeCode_var discType =tc->discriminator_type();
00157 TypeCode_var canonDiscType =get_canonical_typecode(discType.in());
00158 result=_orb->create_union_tc(id,name,canonDiscType.in(),ms);
00159 }
00160 else
00161 {
00162 result=unionDef->type();
00163 }
00164 }
00165 break;
00166
00167 case tk_enum:
00168 {
00169 EnumDef_var enumDef=lookupTc<EnumDef>(*this,tc,id,name);
00170 if(CORBA::is_nil(enumDef))
00171 result=TypeCode::_duplicate(tc);
00172 else
00173 result=enumDef->type();
00174 }
00175 break;
00176
00177 case tk_alias:
00178 {
00179 AliasDef_var aliasDef=lookupTc<AliasDef>(*this,tc,id,name);
00180 if(CORBA::is_nil(aliasDef))
00181 {
00182 TypeCode_var contType =tc->content_type();
00183 TypeCode_var canonContType =get_canonical_typecode(contType.in());
00184 result=_orb->create_alias_tc(id,name,canonContType.in());
00185 }
00186 else
00187 {
00188 result=aliasDef->type();
00189 }
00190 }
00191 break;
00192
00193 case tk_except:
00194 {
00195 ExceptionDef_var exceptionDef=lookupTc<ExceptionDef>(*this,tc,id,name);
00196 if(CORBA::is_nil(exceptionDef))
00197 {
00198 StructMemberSeq ms;
00199 ms.length(tc->member_count());
00200 for(ULong i=0; i<ms.length(); ++i)
00201 {
00202 TypeCode_var memberType=tc->member_type(i);
00203 ms[i].name =CORBA::string_dup(tc->member_name(i));
00204 ms[i].type =get_canonical_typecode(memberType.in());
00205 ms[i].type_def=IDLType::_nil();
00206 }
00207 result=_orb->create_exception_tc(id,name,ms);
00208 }
00209 else
00210 {
00211 result=exceptionDef->type();
00212 }
00213 }
00214 break;
00215
00216 case tk_sequence:
00217 {
00218 TypeCode_var contType =tc->content_type();
00219 TypeCode_var canonContType =get_canonical_typecode(contType.in());
00220 result=_orb->create_sequence_tc(tc->length(),canonContType.in());
00221 }
00222 break;
00223
00224 case tk_array:
00225 {
00226 TypeCode_var contType =tc->content_type();
00227 TypeCode_var canonContType =get_canonical_typecode(contType.in());
00228 result=_orb->create_array_tc(tc->length(),canonContType.in());
00229 }
00230 break;
00231
00232
00233 case tk_null:
00234 case tk_void:
00235 case tk_short:
00236 case tk_long:
00237 case tk_ushort:
00238 case tk_ulong:
00239 case tk_float:
00240 case tk_double:
00241 case tk_boolean:
00242 case tk_char:
00243 case tk_octet:
00244 case tk_any:
00245 case tk_TypeCode:
00246 case tk_Principal:
00247 case tk_string:
00248 #ifdef HAS_LongLong
00249 case tk_longlong:
00250 case tk_ulonglong:
00251 #endif
00252 #ifdef HAS_LongDouble
00253 case tk_longdouble:
00254 #endif
00255 case tk_wchar:
00256 case tk_wstring:
00257 case tk_fixed:
00258 {
00259 result=TypeCode::_duplicate(tc);
00260 }
00261 break;
00262
00263
00264 case tk_value:
00265 case tk_value_box:
00266 case tk_native:
00267 case tk_abstract_interface:
00268 case tk_local_interface:
00269 {
00270 cerr<<"Arrgh! Help!"<<endl;
00271 result=TypeCode::_duplicate(tc);
00272 }
00273 break;
00274
00275 case _np_tk_indirect:
00276 assert(0);
00277
00278 }
00279
00280 assert(!CORBA::is_nil(result));
00281 return result._retn();
00282 }
00283
00284
00285 PrimitiveDef_ptr Repository_impl::get_primitive(PrimitiveKind kind)
00286 {
00287 if(kind==pk_null)
00288 return PrimitiveDef::_nil();
00289
00290 map<PrimitiveKind,PrimitiveDef_impl*>::iterator pos=_primitives.find(kind);
00291 if(pos==_primitives.end())
00292 throw NO_IMPLEMENT();
00293
00294 assert(pos->second);
00295 return pos->second->_this();
00296 }
00297
00298
00299 StringDef_ptr Repository_impl::create_string(ULong bound)
00300 {
00301 DB(5,"Repository::create_string("<<bound<<")")
00302 checkReadonly();
00303 Creche<StringDef_impl> result(new StringDef_impl(bound));
00304 return result.release()->_this();
00305 }
00306
00307
00308 WstringDef_ptr Repository_impl::create_wstring(ULong bound)
00309 {
00310 DB(5,"Repository::create_wstring("<<bound<<")")
00311 checkReadonly();
00312 Creche<WstringDef_impl> result(new WstringDef_impl(bound));
00313 return result.release()->_this();
00314 }
00315
00316
00317 SequenceDef_ptr Repository_impl::create_sequence(
00318 ULong bound,
00319 IDLType_ptr element_type
00320 )
00321 {
00322 DB(5,"Repository::create_sequence("<<bound<<",...)")
00323 checkReadonly();
00324 Creche<SequenceDef_impl> result(new SequenceDef_impl(bound));
00325 result->element_type_def(element_type);
00326 return result.release()->_this();
00327 }
00328
00329
00330 ArrayDef_ptr Repository_impl::create_array(
00331 ULong length,
00332 IDLType_ptr element_type
00333 )
00334 {
00335 DB(5,"Repository::create_array("<<length<<",...)")
00336 checkReadonly();
00337 Creche<ArrayDef_impl> result(new ArrayDef_impl(length));
00338 result->element_type_def(element_type);
00339 return result.release()->_this();
00340 }
00341
00342
00343 FixedDef_ptr Repository_impl::create_fixed(UShort digits, Short scale)
00344 {
00345 DB(5,"Repository::create_fixed("<<digits<<","<<scale<<")")
00346 checkReadonly();
00347 Creche<FixedDef_impl> result(new FixedDef_impl(digits,scale));
00348 return result.release()->_this();
00349 }
00350
00351
00352 void Repository_impl::init(
00353 CORBA::ORB_ptr orb,
00354 bool readonly,
00355 Persist* persist
00356 )
00357 {
00358 _orb=orb;
00359 _readonly=readonly;
00360
00361 const char* action="";
00362 try
00363 {
00364 action="resolve initial reference 'omniINSPOA'";
00365 CORBA::Object_var obj =orb->resolve_initial_references("omniINSPOA");
00366 _omniINSPOA=PortableServer::POA::_narrow(obj);
00367 if(CORBA::is_nil(_omniINSPOA))
00368 throw CORBA::OBJECT_NOT_EXIST(0,CORBA::COMPLETED_NO);
00369
00370 action="resolve initial reference 'RootPOA'";
00371 obj=orb->resolve_initial_references("RootPOA");
00372 PortableServer::POA_var rootPoa =PortableServer::POA::_narrow(obj);
00373 if(CORBA::is_nil(rootPoa))
00374 throw CORBA::OBJECT_NOT_EXIST(0,CORBA::COMPLETED_NO);
00375
00376 action="create Interface Repository's POA";
00377 createPoa(rootPoa.in());
00378
00379 action="resolve initial reference 'DynAnyFactory'";
00380 obj=_orb->resolve_initial_references("DynAnyFactory");
00381 _DynAnyFactory=DynamicAny::DynAnyFactory::_narrow(obj);
00382 if(CORBA::is_nil(_DynAnyFactory))
00383 throw CORBA::OBJECT_NOT_EXIST(0,CORBA::COMPLETED_NO);
00384
00385 action="create primitives.";
00386 _primitives[pk_void] =new PrimitiveDef_impl(pk_void);
00387 _primitives[pk_short] =new PrimitiveDef_impl(pk_short);
00388 _primitives[pk_long] =new PrimitiveDef_impl(pk_long);
00389 _primitives[pk_ushort] =new PrimitiveDef_impl(pk_ushort);
00390 _primitives[pk_ulong] =new PrimitiveDef_impl(pk_ulong);
00391 _primitives[pk_float] =new PrimitiveDef_impl(pk_float);
00392 _primitives[pk_double] =new PrimitiveDef_impl(pk_double);
00393 _primitives[pk_boolean] =new PrimitiveDef_impl(pk_boolean);
00394 _primitives[pk_char] =new PrimitiveDef_impl(pk_char);
00395 _primitives[pk_octet] =new PrimitiveDef_impl(pk_octet);
00396 _primitives[pk_any] =new PrimitiveDef_impl(pk_any);
00397 _primitives[pk_TypeCode] =new PrimitiveDef_impl(pk_TypeCode);
00398 _primitives[pk_Principal] =new PrimitiveDef_impl(pk_Principal);
00399 _primitives[pk_string] =new PrimitiveDef_impl(pk_string);
00400 _primitives[pk_objref] =new PrimitiveDef_impl(pk_objref);
00401 #ifdef HAS_LongLong
00402 _primitives[pk_longlong] =new PrimitiveDef_impl(pk_longlong);
00403 _primitives[pk_ulonglong] =new PrimitiveDef_impl(pk_ulonglong);
00404 #endif
00405 #ifdef HAS_LongDouble
00406 _primitives[pk_longdouble]=new PrimitiveDef_impl(pk_longdouble);
00407 #endif
00408 _primitives[pk_wchar] =new PrimitiveDef_impl(pk_wchar);
00409 _primitives[pk_wstring] =new PrimitiveDef_impl(pk_wstring);
00410
00411 action="activate the Repository's POA";
00412 PortableServer::POAManager_var pman =_poa->the_POAManager();
00413 pman->activate();
00414
00415 action="activate the INS POA";
00416 pman =_omniINSPOA->the_POAManager();
00417 pman->activate();
00418
00419 action="start up persistency";
00420 if(persist)
00421 persist->startup();
00422
00423 action="activate InterfaceRepository 'DefaultRepository'";
00424 activateObjectWithId("DefaultRepository");
00425 }
00426 catch(CORBA::ORB::InvalidName& ex)
00427 {
00428 cerr<<"Failed to "<<action<<". InvalidName"<<endl;
00429 throw;
00430 }
00431 catch(CORBA::TRANSIENT& ex)
00432 {
00433 cerr<<"Failed to "<<action<<". TRANSIENT"<<endl;
00434 throw;
00435 }
00436 catch(CORBA::OBJECT_NOT_EXIST& ex)
00437 {
00438 cerr<<"Failed to "<<action<<". OBJECT_NOT_EXIST"<<endl;
00439 throw;
00440 }
00441 catch(CORBA::SystemException& ex)
00442 {
00443 cerr<<"Failed to "<<action<<"."
00444 IFELSE_OMNIORB4(" "<<ex._name()<<" ("<<ex.NP_minorString()<<")",) <<endl;
00445 throw;
00446 }
00447 catch(CORBA::Exception& ex)
00448 {
00449 cerr<<"Failed to "<<action<<"." IFELSE_OMNIORB4(" "<<ex._name(),) <<endl;
00450 throw;
00451 }
00452 }
00453
00454
00455 Repository_impl::Repository_impl():
00456 _primitives(),
00457 _anonymous(),
00458 _idmap(),
00459 _readonly(false)
00460 {}
00461
00462
00463 Repository_impl::~Repository_impl()
00464 {}
00465
00466
00467 void Repository_impl::uncheckedDestroy()
00468 {
00469 for(map<PrimitiveKind,PrimitiveDef_impl*>::iterator i=_primitives.begin();
00470 i!=_primitives.end();
00471 ++i)
00472 {
00473 assert(i->second);
00474 i->second->uncheckedDestroy();
00475 }
00476 _primitives.clear();
00477 }
00478
00479
00480 bool Repository_impl::canContain(DefinitionKind kind)
00481 {
00482 switch(kind)
00483 {
00484 CASE_TYPEDEF
00485 case dk_Constant:
00486 case dk_Exception:
00487 case dk_Interface:
00488 case dk_Value:
00489 case dk_ValueBox:
00490 case dk_Module:
00491 return true;
00492 default:
00493 return false;
00494 }
00495 }
00496
00497
00498 void Repository_impl::addId(string id, Contained_impl* container)
00499 {
00500 assert(!findId(id));
00501 _idmap[id]=container;
00502 }
00503
00504
00505 void Repository_impl::removeId(string id)
00506 {
00507 map<string,Contained_impl*>::iterator pos =_idmap.find(id);
00508 assert(pos!=_idmap.end());
00509 _idmap.erase(pos);
00510 }
00511
00512
00513 Contained_impl* Repository_impl::findId(string id)
00514 {
00515 map<string,Contained_impl*>::iterator pos =_idmap.find(id);
00516 if(pos==_idmap.end())
00517 return NULL;
00518 else
00519 return pos->second;
00520 }
00521
00522
00523 void Repository_impl::addAnonymous(IDLType_impl* anon)
00524 {
00525
00526
00527 assert(anon);
00528 this->_add_ref();
00529 try
00530 {
00531
00532 assert(_anonymous.find(anon)==_anonymous.end());
00533
00534 CORBA::DefinitionKind anonKind =anon->def_kind();
00535 switch(anonKind)
00536 {
00537 case dk_String:
00538 case dk_Wstring:
00539 case dk_Sequence:
00540 case dk_Array:
00541 case dk_Fixed:
00542 break;
00543
00544 default:
00545 throw CORBA::BAD_PARAM(
00546 IFELSE_OMNIORB4(omni::BAD_PARAM_TargetIsInvalidContainer,4),
00547 CORBA::COMPLETED_NO
00548 );
00549 }
00550
00551 _anonymous.insert(anon);
00552 }
00553 catch(...)
00554 {
00555 this->_remove_ref();
00556 throw;
00557 }
00558 }
00559
00560 void Repository_impl::removeAnonymous(IDLType_impl* anon)
00561 {
00562 set<IDLType_impl*>::iterator pos =_anonymous.find(anon);
00563 assert(pos!=_anonymous.end());
00564 _anonymous.erase(pos);
00565 this->_remove_ref();
00566 }
00567
00568 void Repository_impl::createPoa(PortableServer::POA_ptr rootPoa)
00569 {
00570 using namespace PortableServer;
00571 try
00572 {
00573
00574
00575
00576
00577
00578
00579
00580
00581
00582 CORBA::PolicyList policies;
00583 policies.length(3);
00584 policies[0]=rootPoa->create_lifespan_policy(PERSISTENT);
00585 policies[1]=rootPoa->create_id_assignment_policy(USER_ID);
00586 policies[2]=rootPoa->create_thread_policy(SINGLE_THREAD_MODEL);
00587
00588
00589 _poa=rootPoa->create_POA("IRpoa",POAManager::_nil(),policies);
00590 }
00591 catch(POA::AdapterAlreadyExists& ex)
00592 {
00593 cerr<<"POA::AdapterAlreadyExists"<<endl;
00594 throw;
00595 }
00596 catch(POA::InvalidPolicy& ex)
00597 {
00598 cerr<<"POA::InvalidPolicy: "<<ex.index<<endl;
00599 throw;
00600 }
00601 }
00602
00603
00604 void Repository_impl::reincarnate(const PersistNode &node)
00605 {
00606
00607
00608
00609
00610 map<IRObject_impl*,PersistNode*> todo;
00611
00612
00613 PersistNode* idlTypeNode;
00614 map<string,PersistNode*>::const_iterator i;
00615 if(idlTypeNode=node.child("StringDef"))
00616 {
00617 for(i=idlTypeNode->_child.begin(); i!=idlTypeNode->_child.end(); ++i)
00618 {
00619 CORBA::ULong bound =i->second->attrLong("bound");
00620 DB(5,"Repository::reincarnate string("<<bound<<")")
00621 Creche<StringDef_impl> servant(new StringDef_impl(bound));
00622 servant.release( i->first.c_str() );
00623 }
00624 }
00625 if(idlTypeNode=node.child("WstringDef"))
00626 {
00627 for(i=idlTypeNode->_child.begin(); i!=idlTypeNode->_child.end(); ++i)
00628 {
00629 CORBA::ULong bound =i->second->attrLong("bound");
00630 DB(5,"Repository::reincarnate wstring("<<bound<<")")
00631 Creche<WstringDef_impl> servant(new WstringDef_impl(bound));
00632 servant.release( i->first.c_str() );
00633 }
00634 }
00635 if(idlTypeNode=node.child("SequenceDef"))
00636 {
00637 for(i=idlTypeNode->_child.begin(); i!=idlTypeNode->_child.end(); ++i)
00638 {
00639 CORBA::ULong bound =i->second->attrLong("bound");
00640 DB(5,"Repository::reincarnate sequence("<<bound<<")")
00641 Creche<SequenceDef_impl> servant(new SequenceDef_impl(bound));
00642 todo[servant.get()]=i->second;
00643 servant.release( i->first.c_str() );
00644 }
00645 }
00646 if(idlTypeNode=node.child("ArrayDef"))
00647 {
00648 for(i=idlTypeNode->_child.begin(); i!=idlTypeNode->_child.end(); ++i)
00649 {
00650 CORBA::ULong length =i->second->attrLong("length");
00651 DB(5,"Repository::reincarnate array("<<length<<")")
00652 Creche<ArrayDef_impl> servant(new ArrayDef_impl(length));
00653 todo[servant.get()]=i->second;
00654 servant.release( i->first.c_str() );
00655 }
00656 }
00657 if(idlTypeNode=node.child("FixedDef"))
00658 {
00659 for(i=idlTypeNode->_child.begin(); i!=idlTypeNode->_child.end(); ++i)
00660 {
00661 CORBA::UShort digits =i->second->attrLong("digits");
00662 CORBA::Short scale =i->second->attrLong("scale");
00663 DB(5,"Repository::reincarnate fixed("<<digits<<","<<scale<<")")
00664 Creche<FixedDef_impl> servant(new FixedDef_impl(digits,scale));
00665 servant.release( i->first.c_str() );
00666 }
00667 }
00668
00669
00670 recreate(node.child("NAME"),todo);
00671
00672
00673 for(map<IRObject_impl*,PersistNode*>::iterator i =todo.begin();
00674 i!=todo.end();
00675 ++i)
00676 {
00677 DB(5,"Repository::reincarnate "<<i->second->attrString("id").c_str())
00678 i->first->reincarnate(*i->second);
00679 }
00680 }
00681
00682
00683 void Repository_impl::output(ostream &os)
00684 {
00685
00686 for(set<IDLType_impl*>::iterator i=_anonymous.begin();
00687 i!=_anonymous.end();
00688 ++i)
00689 {
00690 (**i).output(os);
00691 }
00692
00693 outputContents(os);
00694 }
00695
00696 PortableServer::POA_ptr Repository_impl::_default_POA()
00697 {
00698 return PortableServer::POA::_duplicate(_omniINSPOA.in());
00699 }
00700
00701 }