GME  13
MgaParserBC.cpp
Go to the documentation of this file.
00001 #include "stdafx.h"
00002 #include "Parser.h"
00003 #include "MgaParser.h"
00004 #include <xercesc/util/PlatformUtils.hpp>
00005 #include <xercesc/parsers/SAXParser.hpp>
00006 #include <stdio.h>
00007 
00008 #include "../Common/CommonCollection.h"
00009 #include "../Common/CommonMgaTrukk.h"
00010 #include <list>//slist
00011 #include "helper.h"
00012 
00013 // --------------------------- CMgaParser - basic copy closure dumped data parsing
00014 
00015 STDMETHODIMP CMgaParser::ParseClos1(IMgaObject *here, BSTR filename)
00016 {
00017         CHECK_IN(here);
00018 
00019         try
00020         {
00021                 COMTHROW( progress.CoCreateInstance(L"Mga.MgaProgressDlg") );
00022                 COMTHROW( progress->SetTitle(_bstr_t(L"Importing CopyClosured XML data...")) );
00023                 COMTHROW( progress->StartProgressDialog(NULL) );
00024 
00025                 CComObjPtr<IMgaProject> p;
00026                 COMTHROW( here->get_Project(PutOut(p)) );
00027                 ASSERT( p != NULL );
00028                 COMTHROW( p->get_Preferences(&project_prefs_orig) );
00029                 manual_relid_mode = project_prefs_orig & MGAPREF_MANUAL_RELIDS ? true : false;
00030 
00031                 m_GME = get_GME( p); // by zolmol
00032 
00033                 COMTHROW( p->Notify(APPEVENT_XML_IMPORT_SPECIAL_BEGIN));
00034 
00035                 COMTHROW( p->CreateTerritory(NULL, PutOut(territory), NULL) );
00036                 COMTHROW( p->BeginTransaction(territory, TRANSACTION_NON_NESTED) );
00037 
00038                 CComObjPtr<IMgaObject> target;
00039                 COMTHROW(territory->OpenObj(here, PutOut(target)));
00040 
00041                 //by zolmol
00042                 m_maintainGuids = false; // do not preserve guids found in data pasted
00043                 m_target = target;
00044                 m_resolveDerFuncPtr = &CMgaParser::ResolveClosure1Derivation;
00045                 //m_clVer = 1;
00046                 m_clVerStr = _T("1");//end
00047 
00048                 if( m_target && m_GME) 
00049                 {
00050                         CComBSTR bstr, id, nm;
00051                         COMTHROW( m_target->get_ID( &id));
00052                         COMTHROW( m_target->get_Name( &nm));
00053                         COMTHROW(bstr.Append(L"[Closure Parser] Inserting copy closured data into: <A HREF=\"mga:"));
00054                         COMTHROW(bstr.AppendBSTR( id));
00055                         COMTHROW(bstr.Append(L"\">"));
00056                         COMTHROW(bstr.AppendBSTR( nm));
00057                         COMTHROW(bstr.Append(L"</A>"));
00058                         COMTHROW( m_GME->ConsoleMessage(bstr, MSG_INFO));
00059                 }
00060 
00061                 project_prefs = project_prefs_orig | MGAPREF_IGNORECONNCHECKS;
00062                 COMTHROW( p->put_Preferences(project_prefs) );
00063 
00064                 COMTHROW( resolver.CoCreateInstance(L"Mga.MgaResolver") );
00065                 ASSERT( resolver != NULL );
00066 
00067                 project = p;
00068 
00069                 CopyTo(filename, xmlfile);
00070 
00071                 XMLPlatformUtilsTerminate_RAII term;
00072                 try
00073                 {
00074                         XMLPlatformUtils::Initialize();
00075 
00076                         SAXParser parser;
00077                         parser.setValidationScheme(SAXParser::Val_Always);
00078                         parser.setDocumentHandler(this);
00079                         parser.setErrorHandler(this);
00080                         parser.setEntityResolver(this);
00081 
00082                         //elementfuncs = elementfuncs_bcmga;
00083                         funcTableState = BC_MGA;
00084 
00085                         // manual first pass
00086 
00087                         pass_count = 1;
00088 
00089                         ranges.clear();
00090                         ranges.push_front(range_type());
00091                         ranges.front().begin = 1;
00092                         ranges.front().end = (counter_type)-1;
00093                         ranges.front().previous.name = _T("start");
00094                         ranges.front().previous.object = target;
00095                         skip_element_level = 0;
00096                         
00097                         parser.parse(xmlfile.c_str());
00098 
00099                         ASSERT( ranges.front().begin == 1 );
00100                         ranges.pop_front();
00101                         elements.clear();
00102 
00103                         max_counter = counter;
00104 
00105                         // the other passes
00106 
00107                         parser.setValidationScheme(SAXParser::Val_Never);
00108 
00109                         while( !ranges.empty() && ranges.front().begin != (counter_type)-1 )
00110                         {
00111                                 // FIXME: better algorithm for infinite loop
00112                                 if( ++pass_count >= 100 )
00113                                         HR_THROW(E_TOOMANYPASSES);
00114 
00115                                 parser.parse(xmlfile.c_str());
00116                         }
00117 
00118                         ASSERT( elements.empty() );
00119                         ranges.clear();
00120                 }
00121             catch(const XMLException &e)
00122                 {
00123                         XmlStr desc(e.getMessage());
00124 
00125                         ThrowXmlError(L"%s", desc.c_str());
00126                 }
00127                 COMTHROW( project->put_Preferences(project_prefs_orig) );
00128 
00129                 for(librecords::reverse_iterator i = libstodo.rbegin(); i != libstodo.rend(); i++) { // copied from ParseProject in order to recognize libraries (zolmol)
00130                         COMTHROW(i->f->put_LibraryName(CComBSTR(i->libname.c_str())));
00131                         COMTHROW(i->f->put_Exempt(VARIANT_FALSE));
00132                 }
00133                 libstodo.clear();
00134 
00135                 COMTHROW( project->CommitTransaction() );
00136                 COMTHROW( project->Notify(APPEVENT_XML_IMPORT_SPECIAL_END));
00137                 project = NULL;
00138                 clear_GME( m_GME);
00139 
00140                 CloseAll();
00141         }
00142         catch(hresult_exception &e)
00143         {
00144                 CloseAll();
00145                 // in case we rethrew the [probably MGA originated] exception 
00146                 // we have set into errorinfo the location info
00147                 if( m_GME)
00148                         COMTHROW(m_GME->ConsoleMessage( errorinfo, MSG_ERROR));
00149                 clear_GME( m_GME);
00150 
00151                 ASSERT( FAILED(e.hr) );
00152                 if( e.hr == E_XMLPARSER )
00153                         SetErrorInfo(errorinfo);
00154                 else
00155                         SetErrorInfo2(e.hr);
00156 
00157                 return e.hr;
00158         }
00159         return S_OK;
00160 }
00161 
00162 CMgaParser::elementfunc CMgaParser::elementfuncs_bcmga[] = 
00163 {
00164         //elementfunc(_T("project"), StartProject, EndNone),
00165         elementfunc(_T("name"), StartNone, EndName),
00166         elementfunc(_T("comment"), StartNone, EndComment),
00167         elementfunc(_T("author"), StartNone, EndAuthor),
00168         elementfunc(_T("value"), StartNone, EndValue),
00169         elementfunc(_T("regnode"), StartRegNode, EndNone),
00170         elementfunc(_T("attribute"), StartAttribute, EndNone),
00171         elementfunc(_T("constraint"), StartNone, EndConstraint),
00172         elementfunc(_T("folder"), StartFolder, EndNone),
00173         elementfunc(_T("model"), StartModel, EndNone),
00174         elementfunc(_T("atom"), StartAtom, EndNone),
00175         elementfunc(_T("connection"), StartConnection, EndNone),
00176         elementfunc(_T("connpoint"), StartBCConnPoint, EndNone),        // diff
00177         elementfunc(_T("reference"), StartBCReference, EndNone),        // diff
00178         elementfunc(_T("set"), StartBCSet, EndNone),                            // diff
00179         elementfunc(_T("clipboard"), StartBCClipboard, EndNone),        // diff, common for closure clipboards
00180         elementfunc(_T(""), NULL, NULL)
00181 };
00182 
00183 // ------- Element Handlers
00184 void CMgaParser::StartBCClipboard(const attributes_type &attributes)
00185 {
00186         ASSERT( project != NULL );
00187         ASSERT( GetPrevName() == _T("start") );
00188         ASSERT( GetPrevious().object != NULL );
00189 
00190         const CComObjPtr<IUnknown> &obj = GetPrevious().object;
00191         GetCurrent().object = obj;
00192 
00193         CComObjPtr<IMgaModel> model;
00194         CComObjPtr<IMgaFolder> folder;
00195 
00196         if( SUCCEEDED(obj.QueryInterface(model)) )
00197                 GetCurrent().name = _T("model");
00198         else if( SUCCEEDED(obj.QueryInterface(folder)) )
00199                 GetCurrent().name = _T("folder");
00200         else
00201                 HR_THROW(E_INVALID_FILENAME);
00202 
00203         const std::tstring *ver = GetByNameX(attributes, _T("closureversion"));
00204 
00205         ASSERT( ver);
00206         ASSERT( ver->compare(m_clVerStr) == 0);
00207 
00208         const std::tstring *acceptingkinds = GetByNameX(attributes, _T("acceptingkind"));
00209         if( acceptingkinds != NULL)
00210         {
00211                 CComBstrObj kind_name;
00212                 if( model)
00213                 {
00214                         CComObjPtr<IMgaMetaFCO> k_meta;
00215                         COMTHROW( model->get_Meta( PutOut( k_meta)));
00216                         COMTHROW( k_meta->get_Name( PutOut(kind_name)) );
00217                 }
00218                 else if( folder)
00219                 {
00220                         CComObjPtr<IMgaMetaFolder> f_meta;
00221                         COMTHROW( folder->get_MetaFolder( PutOut( f_meta)));
00222                         COMTHROW( f_meta->get_Name( PutOut(kind_name)) );
00223                 }
00224                         
00225                 // check if the accepting kind exists among the accepting kinds
00226                 std::tstring kind_nm;
00227                 CopyTo( kind_name, kind_nm);
00228 
00229                 if( acceptingkinds->empty()) // if _T("") token avoid check
00230                 {
00231                         CComBSTR bstr(L"[Parser] \"clipboard\" element has empty \"acceptingkind\" attribute.");
00232                         if( m_GME) COMTHROW( m_GME->ConsoleMessage(bstr, MSG_WARNING));
00233                 }
00234                 else if( !findExact( *acceptingkinds, kind_nm))
00235                 {
00236                         CComBSTR bstr(L"[Parser] Target kind \"");
00237                         COMTHROW(bstr.Append( kind_nm.c_str()));
00238                         COMTHROW(bstr.Append(L"\" not found among accepting kinds: \""));
00239                         COMTHROW(bstr.Append( acceptingkinds->c_str()));
00240                         COMTHROW(bstr.Append(L"\". If you'd like to avoid this check remove or modify to \"\" the \"acceptingkind\" attribute of \"clipboard\" element in an editor."));
00241                         if( m_GME)
00242                                 COMTHROW( m_GME->ConsoleMessage(bstr, MSG_ERROR));
00243                         HR_THROW(E_INVALID_MGA);
00244                 }
00245 
00246         }
00247 
00248 }
00249 
00250 void CMgaParser::ResolveClosure1Derivation(const attributes_type &attributes, deriv_type &deriv)
00251 {
00252         const std::tstring *s = GetByNameX(attributes, _T("derivedfrom"));
00253         if( s == NULL )
00254         {
00255                 s = GetByNameX(attributes, _T("closurelibderivedfrom"));
00256                 if( s == NULL)
00257                 {
00258                         deriv.from.Release();
00259                         return;
00260                 }
00261 
00262                 CComObjPtr<IMgaObject> obj;
00263             COMTHROW( project->get_ObjectByPath( PutInBstr( *s), PutOut( obj)) );
00264                 if ( obj)
00265                         COMTHROW( obj.QueryInterface( deriv.from));
00266                 else // if nonunique is allowed
00267                 {
00268                         COMTHROW( project->get_NthObjectByPath( 0, PutInBstr( *s), PutOut( obj)) );
00269                         if( obj)
00270                                 COMTHROW( obj.QueryInterface( deriv.from));
00271 
00272                         //<!> warning about non uniqueness
00273                         if( obj && m_GME) 
00274                         {
00275                                 CComBSTR bstr, id, nm;
00276                                 COMTHROW( obj->get_ID( &id));
00277                                 COMTHROW( obj->get_Name( &nm));
00278                                 COMTHROW(bstr.Append(L"[Closure Parser] Name ambiguity found. Selected: <A HREF=\"mga:"));
00279                                 COMTHROW(bstr.AppendBSTR( id));
00280                                 COMTHROW(bstr.Append(L"\">"));
00281                                 COMTHROW(bstr.AppendBSTR( nm));
00282                                 COMTHROW(bstr.Append(L"</A> as basetype. Search path used: "));
00283                                 COMTHROW(bstr.Append( makeViewable(*s).c_str()));
00284 
00285                                 COMTHROW( m_GME->ConsoleMessage(bstr, MSG_ERROR));
00286                         }
00287                 }
00288 
00289                 if ( deriv.from == NULL) // do not throw exception in case of closurelibderivedfrom
00290                 {
00291                         deriv.from.Release();
00292                         return;
00293                 }
00294         }
00295         else
00296         {
00297                 LookupByID(*s, deriv.from);
00298 
00299                 if( deriv.from == NULL )
00300                         throw pass_exception();
00301         }
00302 
00303         s = GetByNameX(attributes, _T("isinstance"));
00304         deriv.isinstance = ( s != NULL && *s == _T("yes") ) ? VARIANT_TRUE : VARIANT_FALSE;
00305 
00306         s = GetByNameX(attributes, _T("isprimary"));
00307         deriv.isprimary = ( s != NULL && *s == _T("no") ) ? false : true;
00308 }
00309 
00310 
00311 void CMgaParser::StartBCConnPoint(const attributes_type &attributes)
00312 {
00313         ASSERT( GetPrevName() == _T("connection") );
00314         CComObjPtr<IMgaConnection> conn;
00315         GetPrevObj(conn);
00316 
00317         if( GetPrevious().exstrinfo == _T("skip") || GetByName(attributes, _T("isbound")) == _T("yes") ) return;
00318 
00319         CComObjPtr<IMgaFCO> target;
00320 
00321         // prefer the closurelibtarget over the target:
00322         const std::tstring *libtg = GetByNameX(attributes, _T("closurelibtarget"));
00323         if ( libtg != NULL)
00324         {
00325                 CComObjPtr<IMgaObject> obj;
00326                 COMTHROW( project->get_ObjectByPath( PutInBstr( *libtg), PutOut( obj)) );
00327                 if ( obj)
00328                         COMTHROW( obj.QueryInterface( target));
00329                 else // if nonunique is allowed
00330                 {
00331                   COMTHROW( project->get_NthObjectByPath( 0, PutInBstr( *libtg), PutOut( obj)) );
00332                         if( obj)
00333                                 COMTHROW( obj.QueryInterface( target));
00334 
00335                         //<!> warning about non uniqueness
00336                         if( obj && m_GME) 
00337                         {
00338                                 CComBSTR bstr, id, nm;
00339                                 COMTHROW( obj->get_ID( &id));
00340                                 COMTHROW( obj->get_Name( &nm));
00341                                 COMTHROW(bstr.Append(L"[Closure Parser] Name ambiguity found. Selected: <A HREF=\"mga:"));
00342                                 COMTHROW(bstr.AppendBSTR( id));
00343                                 COMTHROW(bstr.Append(L"\">"));
00344                                 COMTHROW(bstr.AppendBSTR( nm));
00345                                 COMTHROW(bstr.Append(L"</A> as connection target. Search path used: "));
00346                                 COMTHROW(bstr.Append( makeViewable(*libtg).c_str()));
00347 
00348                                 COMTHROW( m_GME->ConsoleMessage(bstr, MSG_ERROR));
00349                         }
00350                 }
00351         }
00352 
00353         const std::tstring *tg = GetByNameX(attributes, _T("target"));
00354         if( tg != NULL && libtg == NULL) // valid info in target iff no closurelibtarget token
00355         {
00356                 LookupByID( *tg, target);
00357         }
00358 
00359         // throw even if closurelibtarget present but not found the needed object
00360         if ( target == NULL)
00361                 throw pass_exception();
00362 
00363         CComObjPtr<IMgaFCOs> coll;
00364         COMTHROW(coll.CoCreateInstance(L"Mga.MgaFCOs"));
00365 
00366         const std::tstring *s = GetByNameX(attributes, _T("refs"));
00367         if( s != NULL )
00368         {
00369                 int pos = s->find_first_not_of(' ', 0);
00370                 ASSERT( pos >= 0 );
00371                 while( pos < (int) s->length() )
00372                 {
00373                         int pos2 = s->find_first_of(' ', pos);
00374                         if( pos2 < 0 )
00375                                 pos2 = s->length();
00376                         ASSERT( pos2 > pos );
00377 
00378                         CComObjPtr<IMgaFCO> ref;
00379                         LookupByID(std::tstring(*s, pos, pos2-pos), ref);
00380 
00381                         if( ref == NULL )
00382                                 throw pass_exception();
00383 
00384                         COMTHROW(coll->Append(ref));
00385 
00386                         pos = pos2+1;
00387                 }
00388         }
00389 
00390         CComObjPtr<IMgaConnPoint> connpoint;
00391 
00392         COMTHROW( conn->AddConnPoint(PutInBstr(GetByName(attributes, _T("role"))), 0,   // FIXME: multiplicity
00393                 target, coll, PutOut(connpoint)) );
00394 }
00395 
00396 void CMgaParser::StartBCReference(const attributes_type &attributes)
00397 {
00398         CComObjPtr<IMgaFCO> fco;
00399 
00400         deriv_type deriv;
00401         (*this.*m_resolveDerFuncPtr)(attributes, deriv);
00402 
00403         CComObjPtr<IMgaFCO> referred;
00404 
00405         const std::tstring *s = GetByNameX(attributes, _T("referred"));
00406         if( s != NULL )
00407         {
00408                 LookupByID(*s, referred);
00409 
00410                 if( referred == NULL )
00411                         throw pass_exception();
00412         }
00413         else // by ZolMol
00414         {
00415                 s = GetByNameX(attributes, _T("closurelibreferred"));
00416                 if( s != NULL)
00417                 {
00418                         CComObjPtr<IMgaObject> obj;
00419                         COMTHROW( project->get_ObjectByPath( PutInBstr( *s), PutOut( obj)) );
00420                         if ( obj)
00421                                 COMTHROW( obj.QueryInterface( referred));
00422                         else // if nonunique is allowed
00423                         {
00424                                 COMTHROW( project->get_NthObjectByPath( 0, PutInBstr( *s), PutOut( obj)) );
00425                                 if( obj)
00426                                         COMTHROW( obj.QueryInterface( referred));
00427 
00428                                 //<!> warning about non uniqueness
00429                                 if( obj && m_GME) 
00430                                 {
00431                                         CComBSTR bstr, id, nm;
00432                                         COMTHROW( obj->get_ID( &id));
00433                                         COMTHROW( obj->get_Name( &nm));
00434                                         COMTHROW(bstr.Append(L"[Closure Parser] Name ambiguity found. Selected: <A HREF=\"mga:"));
00435                                         COMTHROW(bstr.AppendBSTR( id));
00436                                         COMTHROW(bstr.Append(L"\">"));
00437                                         COMTHROW(bstr.AppendBSTR( nm));
00438                                         COMTHROW(bstr.Append(L"</A> as library reference. Search path used: "));
00439                                         COMTHROW(bstr.Append( makeViewable(*s).c_str()));
00440 
00441                                         COMTHROW( m_GME->ConsoleMessage(bstr, MSG_ERROR));
00442                                 }
00443                         }
00444                 }
00445         }
00446 
00447         if( GetPrevName() == _T("folder") )
00448         {
00449                 CComObjPtr<IMgaFolder> prev;
00450                 GetPrevObj(prev);
00451 
00452                 preparerelid(attributes);
00453                 if( deriv.from != NULL )
00454                 {
00455                         COMTHROW( prev->DeriveRootObject(deriv.from, deriv.isinstance, PutOut(fco)) );
00456                 }
00457                 else
00458                 {
00459                         CComObjPtr<IMgaMetaFCO> meta;
00460                         COMTHROW( resolver->get_KindByStr(prev, PutInBstrAttr(attributes, _T("kind")), 
00461                                 OBJTYPE_REFERENCE, PutOut(meta)) );
00462                         ASSERT( meta != NULL );
00463 
00464                         COMTHROW( prev->CreateRootObject(meta, PutOut(fco)) );
00465                 }
00466                 assignrelid(fco);
00467         }
00468         else
00469         {
00470                 ASSERT( GetPrevName() == _T("model") );
00471                 CComObjPtr<IMgaModel> prev;
00472                 GetPrevObj(prev);
00473 
00474                 CComObjPtr<IMgaMetaRole> role;
00475                 COMTHROW( resolver->get_RoleByStr(prev, 
00476                         PutInBstrAttr(attributes, _T("kind")), OBJTYPE_REFERENCE,
00477                         PutInBstrAttr(attributes, _T("role")), NULL, PutOut(role)) );
00478                 ASSERT( role != NULL );
00479 
00480                 if( deriv.from != NULL )
00481                 {
00482                         CComObjPtr<IMgaReference> derivedfrom;
00483                         COMTHROW( deriv.from.QueryInterface(derivedfrom) );
00484 
00485                         if( deriv.isprimary )
00486                         {
00487                                 preparerelid(attributes);
00488                                 COMTHROW( prev->DeriveChildObject(derivedfrom, role, deriv.isinstance, PutOut(fco)) );
00489                                 assignrelid(fco);
00490                         }
00491                         else
00492                         {
00493                                 COMTHROW( prev->get_ChildDerivedFrom(derivedfrom, PutOut(fco)) );
00494                         }
00495                 }
00496                 else
00497                 {
00498                         preparerelid(attributes);
00499                         COMTHROW( prev->CreateChildObject(role, PutOut(fco)) );
00500                         assignrelid(fco);
00501                 }
00502         }
00503         ASSERT( fco != NULL );
00504 
00505         if( !(GetByName(attributes, _T("isbound")) == _T("yes")) && referred != NULL )
00506         {
00507                 CComObjPtr<IMgaReference> ref;
00508                 COMTHROW( fco.QueryInterface(ref) );
00509 
00510                 COMTHROW( ref->put_Referred(referred) );
00511         }
00512 
00513         GetCurrent().object = fco;
00514 
00515         RegisterLookup(attributes, fco);
00516 }
00517 
00518 void CMgaParser::StartBCSet(const attributes_type &attributes)
00519 {
00520         CComObjPtr<IMgaFCO> fco;
00521 
00522         deriv_type deriv;
00523         (*this.*m_resolveDerFuncPtr)(attributes, deriv);
00524 
00525         std::list< CComObjPtr<IMgaFCO> > members;//slist
00526 
00527         const std::tstring *s = GetByNameX(attributes, _T("members"));
00528         if( s != NULL )
00529         {
00530                 int pos = s->find_first_not_of(' ', 0);
00531                 ASSERT( pos >= 0 );
00532                 while( pos < (int) s->length() )
00533                 {
00534                         int pos2 = s->find_first_of(' ', pos);
00535                         if( pos2 < 0 )
00536                                 pos2 = s->length();
00537                         ASSERT( pos2 > pos );
00538 
00539                         CComObjPtr<IMgaFCO> member;
00540                         LookupByID(std::tstring(*s, pos, pos2-pos), member);
00541 
00542                         if( member == NULL )
00543                                 throw pass_exception();
00544 
00545                         members.push_front(member);
00546 
00547                         pos = pos2+1;
00548                 }
00549         }
00550 
00551         if( GetPrevName() == _T("folder") )
00552         {
00553                 CComObjPtr<IMgaFolder> prev;
00554                 GetPrevObj(prev);
00555 
00556                 preparerelid(attributes);
00557                 if( deriv.from != NULL )
00558                 {
00559                         COMTHROW( prev->DeriveRootObject(deriv.from, deriv.isinstance, PutOut(fco)) );
00560                 }
00561                 else
00562                 {
00563                         CComObjPtr<IMgaMetaFCO> meta;
00564                         COMTHROW( resolver->get_KindByStr(prev, PutInBstrAttr(attributes, _T("kind")), 
00565                                 OBJTYPE_SET, PutOut(meta)) );
00566                         ASSERT( meta != NULL );
00567 
00568                         COMTHROW( prev->CreateRootObject(meta, PutOut(fco)) );
00569                 }
00570                 assignrelid(fco);
00571         }
00572         else
00573         {
00574                 ASSERT( GetPrevName() == _T("model") );
00575                 CComObjPtr<IMgaModel> prev;
00576                 GetPrevObj(prev);
00577 
00578                 CComObjPtr<IMgaMetaRole> role;
00579                 COMTHROW( resolver->get_RoleByStr(prev, 
00580                         PutInBstrAttr(attributes, _T("kind")), OBJTYPE_SET,
00581                         PutInBstrAttr(attributes, _T("role")), NULL, PutOut(role)) );
00582                 ASSERT( role != NULL );
00583 
00584                 if( deriv.from != NULL )
00585                 {
00586                         CComObjPtr<IMgaSet> derivedfrom;
00587                         COMTHROW( deriv.from.QueryInterface(derivedfrom) );
00588 
00589                         if( deriv.isprimary )
00590                         {
00591                                 preparerelid(attributes);
00592                                 COMTHROW( prev->DeriveChildObject(derivedfrom, role, deriv.isinstance, PutOut(fco)) );
00593                                 assignrelid(fco);
00594                         }
00595                         else
00596                         {
00597                                 preparerelid(attributes);
00598                                 COMTHROW( prev->get_ChildDerivedFrom(derivedfrom, PutOut(fco)) );
00599                                 assignrelid(fco);
00600                         }
00601                 }
00602                 else
00603                 {
00604                         preparerelid(attributes);
00605                         COMTHROW( prev->CreateChildObject(role, PutOut(fco)) );
00606                         assignrelid(fco);
00607                 }
00608         }
00609         ASSERT( fco != NULL );
00610 
00611         CComObjPtr<IMgaSet> mgaset;
00612         COMTHROW( fco.QueryInterface(mgaset) );
00613 
00614         if( !(GetByName(attributes, _T("isbound")) == _T("yes")) ) {
00615                 COMTHROW( mgaset->RemoveAll() ); //by ZolMol: if not bound then the members are different, remove the inherited members
00616                 std::list< CComObjPtr<IMgaFCO> >::iterator i = members.begin();//slist
00617                 while( i != members.end() )
00618                 {
00619                         COMTHROW( mgaset->AddMember(*i) );
00620                         ++i;
00621                 }
00622         }
00623         GetCurrent().object = fco;
00624 
00625         RegisterLookup(attributes, fco);
00626 }
00627