GME
13
|
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 #include <algorithm> 00008 00009 #include "../Common/CommonCollection.h" 00010 #include "../Common/CommonMgaTrukk.h" 00011 #include <list>//slist 00012 #include "helper.h" 00013 #include "GUIDcreate.h" 00014 00015 // --------------------------- CMgaParser - copy closure dumped data parsing 00016 00017 STDMETHODIMP CMgaParser::ParseClos4(IMgaObject *here, BSTR filename, int options) 00018 { 00019 CHECK_IN(here); 00020 00021 try 00022 { 00023 COMTHROW( progress.CoCreateInstance(L"Mga.MgaProgressDlg") ); 00024 COMTHROW( progress->SetTitle(_bstr_t(L"Importing SmartCopied XML data...")) ); 00025 COMTHROW( progress->StartProgressDialog(NULL) ); 00026 00027 CComObjPtr<IMgaProject> p; 00028 COMTHROW( here->get_Project(PutOut(p)) ); 00029 ASSERT( p != NULL ); 00030 COMTHROW( p->get_Preferences(&project_prefs_orig) ); 00031 manual_relid_mode = project_prefs_orig & MGAPREF_MANUAL_RELIDS ? true : false; 00032 00033 m_GME = get_GME( p);//by zolmol 00034 00035 COMTHROW( p->Notify(APPEVENT_XML_IMPORT_SPECIAL_BEGIN)); 00036 00037 COMTHROW( p->CreateTerritory(NULL, PutOut(territory), NULL) ); 00038 COMTHROW( p->BeginTransaction(territory, TRANSACTION_NON_NESTED) ); 00039 00040 CComObjPtr<IMgaObject> target; 00041 COMTHROW(territory->OpenObj(here, PutOut(target))); 00042 00043 //by zolmol 00044 m_maintainGuids = false; // do not preserve guids found in data pasted 00045 m_mergeAllowed = (options & MERGE) != 0; 00046 m_target = target; 00047 m_resolveDerFuncPtr = &CMgaParser::ResolveClosure4Derivation; 00048 m_clVerStr = _T("4");//end 00049 00050 project_prefs = project_prefs_orig | MGAPREF_IGNORECONNCHECKS; 00051 COMTHROW( p->put_Preferences(project_prefs) ); 00052 00053 COMTHROW( resolver.CoCreateInstance(L"Mga.MgaResolver") ); 00054 ASSERT( resolver != NULL ); 00055 00056 project = p; 00057 00058 CopyTo(filename, xmlfile); 00059 00060 XMLPlatformUtilsTerminate_RAII term; 00061 try 00062 { 00063 XMLPlatformUtils::Initialize(); 00064 00065 SAXParser parser; 00066 parser.setValidationScheme(SAXParser::Val_Always); 00067 parser.setDocumentHandler(this); 00068 parser.setErrorHandler(this); 00069 parser.setEntityResolver(this); 00070 00071 funcTableState = SC_MGA; 00072 //elementfuncs = elementfuncs_scmga; 00073 00074 // manual first pass 00075 00076 pass_count = 1; 00077 00078 ranges.clear(); 00079 ranges.push_front(range_type()); 00080 ranges.front().begin = 1; 00081 ranges.front().end = (counter_type)-1; 00082 ranges.front().previous.name = _T("start"); 00083 ranges.front().previous.object = target; 00084 skip_element_level = 0; 00085 00086 parser.parse(xmlfile.c_str()); 00087 00088 ASSERT( ranges.front().begin == 1 ); 00089 ranges.pop_front(); 00090 elements.clear(); 00091 00092 max_counter = counter; 00093 00094 // the other passes 00095 00096 parser.setValidationScheme(SAXParser::Val_Never); 00097 00098 while( !ranges.empty() && ranges.front().begin != (counter_type)-1 ) 00099 { 00100 // FIXME: better algorithm for infinite loop 00101 if( ++pass_count >= 1 )//<!> reduced from 100 to 5 00102 { 00103 msgSC( CComBSTR(L"Exception during parsing."), MSG_ERROR); 00104 HR_THROW(E_TOOMANYPASSES); 00105 } 00106 00107 parser.parse(xmlfile.c_str()); 00108 } 00109 00110 ASSERT( elements.empty() ); 00111 ranges.clear(); 00112 00113 if( isNeedFor2ndStep()) 00114 { 00115 CComBSTR bstr1(L"Some objects were not found during parsing."); 00116 CComBSTR bstr2(L"Invoking 2nd step..."); 00117 msgSC( bstr1, MSG_ERROR); 00118 msgSC( bstr2, MSG_INFO); 00119 00120 tryToFindMissedReferreds(); 00121 tryToFindMissedSetMembers(); 00122 } 00123 } 00124 catch(const XMLException &e) 00125 { 00126 XmlStr desc(e.getMessage()); 00127 00128 ThrowXmlError(L"%s", desc.c_str()); 00129 } 00130 COMTHROW( project->put_Preferences(project_prefs_orig) ); 00131 00132 for(librecords::reverse_iterator i = libstodo.rbegin(); i != libstodo.rend(); ++i) { // copied from ParseProject in order to recognize libraries (zolmol) 00133 COMTHROW(i->f->put_LibraryName(CComBSTR(i->libname.c_str()))); 00134 COMTHROW(i->f->put_Exempt(VARIANT_FALSE)); 00135 } 00136 libstodo.clear(); 00137 00138 COMTHROW( project->CommitTransaction() ); 00139 COMTHROW( project->Notify(APPEVENT_XML_IMPORT_SPECIAL_END)); 00140 project = NULL; 00141 clear_GME( m_GME); 00142 00143 CloseAll(); 00144 } 00145 catch(hresult_exception &e) 00146 { 00147 CloseAll(); 00148 // in case we rethrew the [probably MGA originated] exception 00149 // we have set into errorinfo the location info 00150 if( m_GME) 00151 COMTHROW(m_GME->ConsoleMessage( errorinfo, MSG_ERROR)); 00152 clear_GME( m_GME); 00153 00154 ASSERT( FAILED(e.hr) ); 00155 if( e.hr == E_XMLPARSER ) 00156 SetErrorInfo(errorinfo); 00157 else 00158 SetErrorInfo2(e.hr); 00159 00160 return e.hr; 00161 } 00162 return S_OK; 00163 } 00164 00165 CMgaParser::elementfunc CMgaParser::elementfuncs_scmga[] = // special handlers for all elements 00166 { 00167 //elementfunc(_T("project"), StartProject, EndNone), 00168 elementfunc(_T("name"), StartNone, EndSCName), 00169 //elementfunc(_T("comment"), StartNone, EndComment), 00170 //elementfunc(_T("author"), StartNone, EndAuthor), 00171 elementfunc(_T("value"), StartNone, EndSCValue), 00172 elementfunc(_T("regnode"), StartSCRegNode, EndSCRegNode), 00173 elementfunc(_T("attribute"), StartSCAttribute, EndNone), 00174 elementfunc(_T("constraint"), StartNone, EndSCConstraint), 00175 elementfunc(_T("folder"), StartSCFolder, EndNone), 00176 elementfunc(_T("model"), StartSCModel, EndNone), 00177 elementfunc(_T("atom"), StartSCAtom, EndNone), 00178 elementfunc(_T("connection"), StartSCConnection, EndSCConnection), 00179 elementfunc(_T("connpoint"), StartSCConnPoint, EndNone), 00180 elementfunc(_T("reference"), StartSCReference, EndNone), 00181 elementfunc(_T("set"), StartSCSet, EndNone), 00182 elementfunc(_T("clipboard"), StartBCClipboard, EndNone), // common for closures 00183 elementfunc(_T(""), NULL, NULL) 00184 }; 00185 00186 void CMgaParser::ResolveClosure4Derivation(const attributes_type &attributes, deriv_type &deriv) 00187 { 00188 const std::tstring *s = GetByNameX(attributes, _T("derivedfrom")); 00189 if( s == NULL ) 00190 { 00191 s = GetByNameX(attributes, _T("closurelibderivedfrom")); 00192 if( s != NULL) 00193 { 00194 CComObjPtr<IMgaObject> obj; 00195 findObjOnAbsPath( project, *s, obj, _T("archetype")); 00196 if( obj) 00197 COMTHROW( obj.QueryInterface( deriv.from)); 00198 else 00199 { 00200 CComBSTR bstr(L"Archetype can not be found in library. Basetype lost. "); 00201 COMTHROW(bstr.Append(L"Search path used: ")); 00202 COMTHROW(bstr.Append( makeViewable(*s).c_str())); 00203 msgSC( bstr, MSG_ERROR); 00204 } 00205 00206 } 00207 else //if( s == NULL) 00208 { 00209 const std::tstring* g; 00210 g = GetByNameX( attributes, _T("smartDerivedFromGUID")); 00211 s = GetByNameX( attributes, _T("closure2derivedfrom")); 00212 00213 std::tstring rel_path_changed = s? *s: _T(""); 00214 // since the derfrom is calculated relatively to the fco, 00215 // we have to modify the path so that it could be found 00216 // with a search starting from its container 00217 if( rel_path_changed.substr(0, 4) == _T("/@..")) 00218 rel_path_changed = rel_path_changed.substr(4); 00219 // else: the object has similar name to its archetype 00220 // else: the derfrom object cannot be inside the derived object 00221 00222 CComObjPtr<IMgaObject> place; 00223 GetPrevObj(place); 00224 00225 if( g != NULL) 00226 { 00227 if( s != NULL) // try a combined search stepping up in the hierarchy then use guid 00228 findFCOWithRelPathAndGUID( place, rel_path_changed, *g, deriv.from); 00229 00230 if( !deriv.from) // not found, then search in the whole project with GUID 00231 { 00232 CComObjPtr<IMgaProject> pr; 00233 COMTHROW( place->get_Project( PutOut( pr))); 00234 CComObjPtr<IMgaFolder> rf; 00235 COMTHROW( pr->get_RootFolder( PutOut( rf))); 00236 findFCOWithGUIDInTree( CComObjPtr<IMgaObject>( rf), *g, deriv.from); 00237 } 00238 } 00239 00240 if( !deriv.from && s != NULL) 00241 { 00242 CComObjPtr<IMgaObject> obj; 00243 findObjOnRelPath( CComObjPtr<IMgaObject>(place), rel_path_changed, obj, _T("archetype")); 00244 00245 if( obj) 00246 COMTHROW( obj.QueryInterface( deriv.from)); 00247 else // error report 00248 { 00249 CComBSTR bstr(L"Archetype can not be found. Basetype lost. "); 00250 COMTHROW(bstr.Append(L"Search path used: ")); 00251 COMTHROW(bstr.Append( makeViewable(rel_path_changed).c_str())); 00252 msgSC( bstr, MSG_ERROR); 00253 } 00254 } 00255 } 00256 00257 00258 if ( deriv.from == NULL) // do not throw exception in case of closurelibderivedfrom 00259 { 00260 deriv.from.Release(); 00261 return; 00262 } 00263 } 00264 else 00265 { 00266 LookupByID(*s, deriv.from); 00267 00268 if( deriv.from == NULL ) 00269 throw pass_exception(); 00270 } 00271 00272 s = GetByNameX(attributes, _T("isinstance")); 00273 deriv.isinstance = ( s != NULL && *s == _T("yes") ) ? VARIANT_TRUE : VARIANT_FALSE; 00274 00275 s = GetByNameX(attributes, _T("isprimary")); 00276 deriv.isprimary = ( s != NULL && *s == _T("no") ) ? false : true; 00277 } 00278 00279 // ------- Element Handlers 00280 void CMgaParser::StartSCConnection(const attributes_type &attributes) 00281 { 00282 bool skip_inner_elements = false; 00283 CComObjPtr<IMgaFCO> conn; 00284 deriv_type deriv; 00285 //ResolveDerivation(attributes, deriv); 00286 (*this.*m_resolveDerFuncPtr)(attributes, deriv); 00287 00288 if( GetPrevName() == _T("folder") ) 00289 { 00290 CComObjPtr<IMgaFolder> prev; 00291 GetPrevObj(prev); 00292 00293 preparerelid(attributes); 00294 if( deriv.from != NULL ) 00295 { 00296 COMTHROW( prev->DeriveRootObject(deriv.from, deriv.isinstance, PutOut(conn)) ); 00297 00298 // user info 00299 CComBSTR msg = makeLink( conn, makeNameViewable( GetByName(attributes, _T("closurename"))), true); 00300 COMTHROW(msg.Append( L" connection derived from ")); 00301 COMTHROW(msg.AppendBSTR( makeLink( deriv.from))); 00302 msgSC( msg, MSG_INFO); 00303 } 00304 else 00305 { 00306 CComObjPtr<IMgaMetaFCO> meta; 00307 COMTHROW( resolver->get_KindByStr(prev, PutInBstrAttr(attributes, _T("kind")), 00308 OBJTYPE_CONNECTION, PutOut(meta)) ); 00309 ASSERT( meta != NULL ); 00310 00311 COMTHROW( prev->CreateRootObject(meta, PutOut(conn)) ); 00312 } 00313 assignrelid(conn); 00314 } 00315 else 00316 { 00317 ASSERT( GetPrevName() == _T("model") ); 00318 00319 CComObjPtr<IMgaModel> prev; 00320 GetPrevObj(prev); 00321 00322 CComObjPtr<IMgaMetaRole> role; 00323 COMTHROW( resolver->get_RoleByStr(prev, 00324 PutInBstrAttr(attributes, _T("kind")), OBJTYPE_CONNECTION, 00325 PutInBstrAttr(attributes, _T("role")), NULL, PutOut(role)) ); 00326 ASSERT( role != NULL ); 00327 00328 if( deriv.from != NULL ) 00329 { 00330 CComObjPtr<IMgaConnection> derivedfrom; 00331 COMTHROW( deriv.from.QueryInterface(derivedfrom) ); 00332 00333 if( deriv.isprimary ) 00334 { 00335 preparerelid(attributes); 00336 COMTHROW( prev->DeriveChildObject(derivedfrom, role, deriv.isinstance, PutOut(conn)) ); 00337 assignrelid(conn); 00338 } 00339 else 00340 { 00341 COMTHROW( prev->get_ChildDerivedFrom(derivedfrom, PutOut(conn)) ); 00342 } 00343 00344 // user info 00345 CComBSTR msg = makeLink( conn, makeNameViewable( GetByName(attributes, _T("closurename"))), true); 00346 COMTHROW(msg.Append( L" connection derived from ")); 00347 COMTHROW(msg.AppendBSTR( makeLink( deriv.from))); 00348 msgSC( msg, MSG_INFO); 00349 } 00350 else 00351 { 00352 // 'attributes' contains the id of the object (in the source project) 00353 bool found = findObject( prev, attributes, conn, 'C'); 00354 00355 // create only if not found 00356 if( !found) 00357 { 00358 // parse the connection end info 00359 CComObjPtr<IMgaFCO> o1, o2; 00360 CComObjPtr<IMgaFCOs> chain1, chain2; 00361 parseConnection( CComObjPtr<IMgaObject>( prev), attributes, o1, o2, chain1, chain2); 00362 if( o1 && o2) 00363 { 00364 preparerelid(attributes); 00365 COMTHROW( prev->CreateSimpleConn( role, o1, o2, chain1, chain2, PutOut(conn))); 00366 assignrelid(conn); 00367 00368 // user info 00369 CComBSTR msg = makeLink( conn, makeNameViewable( GetByName(attributes, _T("closurename")))); 00370 COMTHROW(msg.Append( L" connection created.")); 00371 msgSC( msg, MSG_INFO); 00372 } 00373 else 00374 { 00375 // error, could not find a correct reference chain 00376 CComBSTR bstr(L"Connection \""); 00377 COMTHROW(bstr.Append( makeNameViewable( GetByName(attributes, _T("closurename"))).c_str())); 00378 COMTHROW(bstr.Append(L"\": could not be created.")); 00379 msgSC( bstr, MSG_ERROR); 00380 00381 bstr.Empty(); 00382 COMTHROW(bstr.Append(L" Reference chain involved: ")); 00383 if( !o1) 00384 COMTHROW(bstr.Append( makeViewable( GetByName( attributes, _T("smart0RefChain") )).c_str())); 00385 else if( !o2) 00386 COMTHROW(bstr.Append( makeViewable( GetByName( attributes, _T("smart1RefChain") )).c_str())); 00387 msgSC( bstr, MSG_ERROR); 00388 00389 bstr.Empty(); 00390 COMTHROW(bstr.Append(L" Target path used: ")); 00391 if( !o1) 00392 COMTHROW(bstr.Append( makeViewable( GetByName( attributes, _T("smart0Target") )).c_str())); 00393 else if( !o2) 00394 COMTHROW(bstr.Append( makeViewable( GetByName( attributes, _T("smart1Target") )).c_str())); 00395 msgSC( bstr, MSG_ERROR); 00396 00397 // to safely pass through hard times (parsing internal connpoints, attributes, regnodes... 00398 // we create a temporary connection with "handicapped" extrsinfo 00399 // which will be deleted by EndSCConnection 00400 00401 preparerelid(attributes); 00402 COMTHROW( prev->CreateChildObject(role, PutOut(conn)) ); 00403 assignrelid(conn); 00404 00405 GetCurrent().exstrinfo = _T("handicapped"); 00406 } 00407 } 00408 else // will skip contained elements/attribute values/regnode entries/constraints/name element 00409 { // will use the object found 00410 skip_inner_elements = true; 00411 00412 // user info 00413 CComBSTR msg = L"Merging "; 00414 COMTHROW(msg.AppendBSTR(makeLink( conn))); 00415 COMTHROW(msg.Append( L" connection.")); 00416 msgSC( msg, MSG_INFO); 00417 } 00418 00419 } 00420 } 00421 ASSERT( conn != NULL ); 00422 GetCurrent().object = conn; 00423 00424 if( GetByName(attributes, _T("isbound")) == _T("yes") 00425 || skip_inner_elements) 00426 GetCurrent().exstrinfo = _T("skip"); 00427 00428 RegisterLookup(attributes, conn); 00429 } 00430 00431 bool CMgaParser::findConnectionEnd 00432 ( CComObjPtr<IMgaObject> pPrev 00433 , const std::tstring& isbound 00434 , const std::tstring& role 00435 , const std::tstring& targetGUID 00436 , const std::tstring& targetPATH 00437 , const std::tstring& refchainGUID 00438 , const std::tstring& refchainPATH 00439 , CComObjPtr<IMgaFCO>& pFoundObj 00440 , CComObjPtr<IMgaFCOs>& pFoundRefChain 00441 ) 00442 { 00443 std::vector< std::tstring> guid_closure_ref_vec; 00444 if( !refchainGUID.empty()) 00445 { 00446 int pos = refchainGUID.find_first_not_of(' ', 0); 00447 ASSERT( pos >= 0 ); 00448 while( pos < (int) refchainGUID.length() ) 00449 { 00450 int pos2 = refchainGUID.find_first_of(' ', pos); 00451 if( pos2 < 0 ) 00452 pos2 = refchainGUID.length(); 00453 ASSERT( pos2 > pos ); 00454 00455 00456 guid_closure_ref_vec.push_back( std::tstring(refchainGUID, pos, pos2-pos)); 00457 pos = pos2+1; 00458 } 00459 } 00460 00461 std::vector< std::tstring> name_closure_ref_vec; 00462 if( !refchainPATH.empty()) 00463 { 00464 int pos = refchainPATH.find_first_not_of(' ', 0); 00465 ASSERT( pos >= 0 ); 00466 while( pos < (int) refchainPATH.length() ) 00467 { 00468 int pos2 = refchainPATH.find_first_of(' ', pos); 00469 if( pos2 < 0 ) 00470 pos2 = refchainPATH.length(); 00471 ASSERT( pos2 > pos ); 00472 00473 00474 name_closure_ref_vec.push_back( std::tstring(refchainPATH, pos, pos2-pos)); 00475 pos = pos2+1; 00476 } 00477 } 00478 00479 if( guid_closure_ref_vec.size() < name_closure_ref_vec.size()) 00480 guid_closure_ref_vec.clear(); // invalid guid chain string info 00481 00482 // will try to reconstruct the reference chain (into pFoundRefChain) based on the refs and closure2refs attribute value 00483 COMTHROW( pFoundRefChain.CoCreateInstance(L"Mga.MgaFCOs")); 00484 00485 CComObjPtr<IMgaModel> container; // this is the container we will look in for the target 00486 00487 if( !guid_closure_ref_vec.empty()) 00488 { 00489 // based on guid 00490 00491 // try to find the first elements in the ref chain inside the container where conn is present 00492 CComObjPtr<IMgaFCO> next_obj; 00493 CComObjPtr<IMgaFCO> last_obj; // this will be a model 00494 00495 // search based on closurerefs 00496 findFCOWithGUID( CComObjPtr<IMgaObject>( pPrev), guid_closure_ref_vec[0], next_obj); 00497 00498 // we will build up the collection of references 00499 unsigned int i; 00500 for( i = 0; next_obj != 0 && i < guid_closure_ref_vec.size(); ++i) 00501 { 00502 // we don't have to deal with name_closure_ref_vec[i] except if i == 0 00503 // just inquire the referred object by next_obj reference 00504 00505 objtype_enum type; 00506 COMTHROW( next_obj->get_ObjType( &type)); 00507 if( type == OBJTYPE_REFERENCE) 00508 { 00509 CComObjPtr<IMgaReference> ref; 00510 COMTHROW( next_obj.QueryInterface( ref)); 00511 if( ref) 00512 { 00513 CComObjPtr<IMgaFCO> refd; 00514 COMTHROW( ref->get_Referred( PutOut( refd))); 00515 00516 if( refd) 00517 { 00518 // we could check the guid of refd against guid_closure_ref_vec[i] 00519 00520 // put the latest valid reference at the end of the collection 00521 COMTHROW(pFoundRefChain->Append(next_obj)); 00522 00523 objtype_enum type; 00524 COMTHROW( refd->get_ObjType( &type)); 00525 if( type == OBJTYPE_REFERENCE) 00526 next_obj = refd; 00527 else 00528 { 00529 next_obj = 0; 00530 if( type == OBJTYPE_MODEL) 00531 last_obj = refd; 00532 } 00533 } 00534 } 00535 } 00536 } 00537 // i == size should we check this? 00538 if( i == guid_closure_ref_vec.size() && last_obj) COMTHROW( last_obj.QueryInterface( container)); 00539 } 00540 00541 if( !container && name_closure_ref_vec.size() > 0) // not found based on GUID 00542 { 00543 // try to find the first elements in the ref chain inside the container where conn is present 00544 00545 CComObjPtr<IMgaFCO> next_obj; 00546 CComObjPtr<IMgaFCO> last_obj; // this will be a model 00547 00548 CComObjPtr<IMgaObject> nx_obj; 00549 00550 // search based on closurerefs 00551 findObjOnRelPath( CComObjPtr<IMgaObject>( pPrev), name_closure_ref_vec[0], nx_obj, _T("reference chain")); 00552 if( nx_obj) COMTHROW( nx_obj.QueryInterface( next_obj)); 00553 00554 // we will build up the collection of references 00555 unsigned int i; 00556 for( i = 0; next_obj != 0 && i < name_closure_ref_vec.size(); ++i) 00557 { 00558 // we don't have to deal with name_closure_ref_vec[i] except if i == 0 00559 // just inquire the referred object by next_obj reference 00560 00561 objtype_enum type; 00562 COMTHROW( next_obj->get_ObjType( &type)); 00563 if( type == OBJTYPE_REFERENCE) 00564 { 00565 CComObjPtr<IMgaReference> ref; 00566 COMTHROW( next_obj.QueryInterface( ref)); 00567 if( ref) 00568 { 00569 CComObjPtr<IMgaFCO> refd; 00570 COMTHROW( ref->get_Referred( PutOut( refd))); 00571 00572 if( refd) 00573 { 00574 // put the latest valid reference at the end of the collection 00575 COMTHROW(pFoundRefChain->Append(next_obj)); 00576 00577 objtype_enum type; 00578 COMTHROW( refd->get_ObjType( &type)); 00579 if( type == OBJTYPE_REFERENCE) 00580 next_obj = refd; 00581 else 00582 { 00583 next_obj = 0; 00584 if( type == OBJTYPE_MODEL) 00585 last_obj = refd; 00586 } 00587 } 00588 } 00589 } 00590 } 00591 00592 // i == size should we check this? 00593 if( i == name_closure_ref_vec.size() && last_obj) COMTHROW( last_obj.QueryInterface( container)); 00594 } 00595 00596 else // plain connection 00597 { 00598 CComQIPtr<IMgaModel> m( pPrev); 00599 container = m; // must be in a model 00600 } 00601 00602 00603 if( !container) 00604 { 00605 //throw pass_exception(); 00606 //pFoundRefChain->removeall(); 00607 return false; 00608 } 00609 else // container is a valid model 00610 { // find the target object in it identified by targetGUID/targetPATH 00611 if( !targetGUID.empty()) 00612 { 00613 findFCOWithGUID( CComObjPtr<IMgaObject>( pPrev), targetGUID, pFoundObj); 00614 } 00615 00616 if( !pFoundObj && !targetPATH.empty()) 00617 { 00618 CComObjPtr<IMgaObject> t_target; 00619 findObjOnRelPath( CComObjPtr<IMgaObject>( pPrev), targetPATH, t_target, _T("target")); 00620 if( t_target) COMTHROW( t_target.QueryInterface( pFoundObj)); 00621 } 00622 } 00623 00624 return (pFoundObj != 0); 00625 } 00626 00627 bool CMgaParser::parseConnection 00628 ( CComObjPtr<IMgaObject> pPrev 00629 , const attributes_type &pAttributes 00630 , CComObjPtr<IMgaFCO>& pSrcObj 00631 , CComObjPtr<IMgaFCO>& pDstObj 00632 , CComObjPtr<IMgaFCOs>& pFoundSrcRefChain 00633 , CComObjPtr<IMgaFCOs>& pFoundDstRefChain 00634 ) 00635 { 00636 const TCHAR *role_attr [] = { _T("smart0Role") , _T("smart1Role") }; 00637 const TCHAR *targetGUID_attr [] = { _T("smart0TargetGUID") , _T("smart1TargetGUID") }; 00638 const TCHAR *target_attr [] = { _T("smart0Target") , _T("smart1Target") }; 00639 const TCHAR *refchainGUID_attr[]= { _T("smart0RefChainGUID") , _T("smart1RefChainGUID") }; 00640 const TCHAR *refchain_attr [] = { _T("smart0RefChain") , _T("smart1RefChain") }; 00641 const TCHAR *isbound_attr [] = { _T("smart0IsBound") , _T("smart1IsBound") }; 00642 00643 CComObjPtr<IMgaFCO> obj[2]; 00644 CComObjPtr<IMgaFCOs> coll[2]; 00645 for( int i = 0 ; i < 2; ++i) 00646 { 00647 std::tstring isbound = GetByName( pAttributes, isbound_attr[i]); 00648 std::tstring role = GetByName( pAttributes, role_attr[i]); 00649 std::tstring targetGUID = GetByName( pAttributes, targetGUID_attr[i]); 00650 std::tstring refchainGUID = GetByName( pAttributes, refchainGUID_attr[i]); 00651 std::tstring target = GetByName( pAttributes, target_attr[i]); 00652 std::tstring refchain = GetByName( pAttributes, refchain_attr[i]); 00653 findConnectionEnd( pPrev, isbound, role, targetGUID, target, refchainGUID, refchain, obj[i], coll[i]); 00654 } 00655 00656 if( obj[0] && obj[1]) 00657 { 00658 pSrcObj = obj[0]; 00659 pDstObj = obj[1]; 00660 pFoundSrcRefChain = coll[0]; 00661 pFoundDstRefChain = coll[1]; 00662 return true; 00663 } 00664 00665 return false; 00666 } 00667 00668 00669 void CMgaParser::EndSCConnection() 00670 { 00671 CComObjPtr<IMgaConnection> fresh_conn; 00672 00673 ASSERT( GetCurrent().object); 00674 COMTHROW( GetCurrent().object.QueryInterface( fresh_conn)); 00675 if( !fresh_conn) 00676 { 00677 ASSERT(0); // it should be a connection at least 00678 return; 00679 } 00680 00681 CComObjPtrVector<IMgaConnPoint> cps; 00682 COMTHROW( fresh_conn->get_ConnPoints( PutOut( cps))); 00683 if( cps.size() < 2 || GetCurrent().exstrinfo == _T("handicapped")) // handicapped connection, error must have occurred 00684 { 00685 COMTHROW( fresh_conn->DestroyObject()); 00686 return; 00687 } 00688 } 00689 00690 void CMgaParser::StartSCConnPoint(const attributes_type &attributes) 00691 { 00692 } 00693 00694 void CMgaParser::StartSCReference(const attributes_type &attributes) 00695 { 00696 CComObjPtr<IMgaObject> obj_prev; 00697 bool skip_inner_elements = false; 00698 bool needs_target = true; 00699 CComObjPtr<IMgaFCO> fco; 00700 00701 deriv_type deriv; 00702 //ResolveDerivation(attributes, deriv); 00703 (*this.*m_resolveDerFuncPtr)(attributes, deriv); 00704 00705 CComObjPtr<IMgaFCO> referred; 00706 00707 if( GetPrevName() == _T("folder") ) 00708 { 00709 CComObjPtr<IMgaFolder> prev; 00710 GetPrevObj(prev); 00711 obj_prev = prev; 00712 00713 if( deriv.from != NULL ) 00714 { 00715 preparerelid(attributes); 00716 COMTHROW( prev->DeriveRootObject(deriv.from, deriv.isinstance, PutOut(fco)) ); 00717 assignrelid(fco); 00718 00719 // user info 00720 CComBSTR msg = makeLink( fco, makeNameViewable( GetByName(attributes, _T("closurename"))), true); 00721 COMTHROW(msg.Append( _T(" reference derived from "))); 00722 COMTHROW(msg.AppendBSTR( makeLink( deriv.from))); 00723 msgSC( msg, MSG_INFO); 00724 00725 } 00726 else 00727 { 00728 // 'attributes' contains the id of the object (in the source project) 00729 bool found = findObject( prev, attributes, fco, 'R'); 00730 00731 // create only if not found 00732 if( !found) 00733 { 00734 CComObjPtr<IMgaMetaFCO> meta; 00735 COMTHROW( resolver->get_KindByStr(prev, PutInBstrAttr(attributes, _T("kind")), 00736 OBJTYPE_REFERENCE, PutOut(meta)) ); 00737 ASSERT( meta != NULL ); 00738 00739 preparerelid(attributes); 00740 COMTHROW( prev->CreateRootObject(meta, PutOut(fco)) ); 00741 assignrelid(fco); 00742 00743 // user info 00744 CComBSTR msg = makeLink( fco, makeNameViewable( GetByName(attributes, _T("closurename")))); 00745 COMTHROW(msg.Append( _T(" reference created."))); 00746 msgSC( msg, MSG_INFO); 00747 } 00748 else // will skip contained elements/attribute values/regnode entries/constraints/name element 00749 { // will use the object found 00750 skip_inner_elements = true; 00751 needs_target = isNullRef( fco); 00752 00753 // user info 00754 CComBSTR msg = L"Merging "; 00755 COMTHROW(msg.AppendBSTR(makeLink( fco))); 00756 if( needs_target) 00757 COMTHROW(msg.Append(L" null")); 00758 COMTHROW(msg.Append( L" reference.")); 00759 msgSC( msg, MSG_INFO); 00760 } 00761 } 00762 } 00763 else 00764 { 00765 ASSERT( GetPrevName() == _T("model") ); 00766 00767 CComObjPtr<IMgaModel> prev; 00768 GetPrevObj(prev); 00769 obj_prev = prev; 00770 00771 CComObjPtr<IMgaMetaRole> role; 00772 COMTHROW( resolver->get_RoleByStr(prev, 00773 PutInBstrAttr(attributes, _T("kind")), OBJTYPE_REFERENCE, 00774 PutInBstrAttr(attributes, _T("role")), NULL, PutOut(role)) ); 00775 ASSERT( role != NULL ); 00776 00777 if( deriv.from != NULL ) 00778 { 00779 CComObjPtr<IMgaReference> derivedfrom; 00780 COMTHROW( deriv.from.QueryInterface(derivedfrom) ); 00781 00782 if( deriv.isprimary ) 00783 { 00784 preparerelid(attributes); 00785 COMTHROW( prev->DeriveChildObject(derivedfrom, role, deriv.isinstance, PutOut(fco)) ); 00786 assignrelid(fco); 00787 } 00788 else 00789 { 00790 COMTHROW( prev->get_ChildDerivedFrom(derivedfrom, PutOut(fco)) ); 00791 } 00792 00793 // user info 00794 CComBSTR msg = makeLink( fco, makeNameViewable( GetByName(attributes, _T("closurename"))), true); 00795 COMTHROW(msg.Append( L" reference derived from ")); 00796 COMTHROW(msg.AppendBSTR( makeLink( deriv.from))); 00797 msgSC( msg, MSG_INFO); 00798 } 00799 else 00800 { 00801 // 'attributes' contains the id of the object (in the source project) 00802 bool found = findObject( prev, attributes, fco, 'R'); 00803 00804 // create only if not found 00805 if( !found) 00806 { 00807 preparerelid(attributes); 00808 COMTHROW( prev->CreateChildObject(role, PutOut(fco)) ); 00809 assignrelid(fco); 00810 00811 // user info 00812 CComBSTR msg = makeLink( fco, makeNameViewable( GetByName(attributes, _T("closurename")))); 00813 COMTHROW(msg.Append( L" reference created.")); 00814 msgSC( msg, MSG_INFO); 00815 } 00816 else // will skip contained elements/attribute values/regnode entries/constraints/name element 00817 { // will use the object found 00818 skip_inner_elements = true; 00819 needs_target = isNullRef( fco); 00820 00821 // user info 00822 CComBSTR msg = "LMerging "; 00823 COMTHROW(msg.AppendBSTR(makeLink( fco))); 00824 if( needs_target) 00825 COMTHROW(msg.Append(L" null")); 00826 COMTHROW(msg.Append( L" reference.")); 00827 msgSC( msg, MSG_INFO); 00828 } 00829 } 00830 00831 } 00832 ASSERT( fco != NULL ); 00833 //fco is the reference just created or selected from the already existing ones 00834 00835 bool bound = GetByName(attributes, _T("isbound")) == _T("yes"); // if bound it does NOT need referees set by hand 00836 if( needs_target && !bound) 00837 { 00838 const std::tstring *s; 00839 s = GetByNameX(attributes, _T("closurelibreferred")); 00840 if( s != NULL) 00841 { 00842 CComObjPtr<IMgaObject> obj; 00843 findObjOnAbsPath( project, *s, obj, _T("referred object")); 00844 00845 if( obj) 00846 COMTHROW( obj.QueryInterface( referred)); 00847 else // report error 00848 { 00849 CComBSTR bstr("Reference "); 00850 COMTHROW(bstr.Append( makeLink( fco, makeNameViewable( GetByName( attributes, _T("closurename"))), true))); 00851 COMTHROW(bstr.Append(": target not found in library. ")); 00852 COMTHROW(bstr.Append("Search path used: ")); 00853 COMTHROW(bstr.Append( makeViewable( *s).c_str())); 00854 msgSC(bstr, MSG_ERROR); 00855 } 00856 } 00857 00858 if( s == NULL || !referred) 00859 { 00860 // first try to find referred object based on GUID 00861 std::tstring guid = GetByName(attributes, _T("smartReferredGUID")); 00862 std::tstring path = GetByName(attributes, _T("closure2referred")); 00863 00864 if( !guid.empty()) 00865 { 00866 if( !path.empty()) 00867 { 00868 // use closure2referred info for stepping up in the hierarchy (if needed) and only then use search on GUID 00869 findFCOWithRelPathAndGUID( CComObjPtr<IMgaObject>( fco), path, guid, referred); 00870 } 00871 00872 if( !referred) // not found, then search in the whole project with GUID 00873 { 00874 CComObjPtr<IMgaProject> pr; 00875 COMTHROW( obj_prev->get_Project( PutOut( pr))); 00876 CComObjPtr<IMgaFolder> rf; 00877 COMTHROW( pr->get_RootFolder( PutOut( rf))); 00878 findFCOWithGUIDInTree( CComObjPtr<IMgaObject>( rf), guid, referred); 00879 } 00880 } 00881 00882 // finally perform a closure2referred based search 00883 if( !referred && !path.empty()) 00884 { 00885 CComObjPtr<IMgaObject> obj; 00886 findObjOnRelPath( CComObjPtr<IMgaObject>(fco), path, obj, _T("referred object")); 00887 00888 if ( obj) 00889 COMTHROW( obj.QueryInterface( referred)); 00890 else // report error 00891 { 00892 CComBSTR bstr("Reference "); 00893 COMTHROW(bstr.Append( makeLink( fco, makeNameViewable( GetByName( attributes, _T("closurename"))), true))); 00894 COMTHROW(bstr.Append(": target not found. ")); 00895 COMTHROW(bstr.Append("Search path used: ")); 00896 COMTHROW(bstr.Append( makeViewable( path).c_str())); 00897 msgSC(bstr, MSG_ERROR); 00898 00899 // store data to process in 2nd step 00900 m_notFoundReferredObject[ fco ] = path; 00901 } 00902 } 00903 } 00904 00905 //WAS: if( !(GetByName(attributes, "isbound") == "yes") && referred != NULL ) 00906 if( referred != NULL ) 00907 { 00908 CComObjPtr<IMgaReference> ref; 00909 COMTHROW( fco.QueryInterface(ref) ); 00910 00911 COMTHROW( ref->put_Referred(referred) ); 00912 } 00913 } 00914 00915 GetCurrent().object = fco; 00916 if( skip_inner_elements) 00917 GetCurrent().exstrinfo = _T("skip"); 00918 00919 RegisterLookup(attributes, fco); 00920 } 00921 00922 void CMgaParser::StartSCSet(const attributes_type &attributes) 00923 { 00924 CComObjPtr<IMgaObject> obj_prev; 00925 bool skip_inner_elements = false; 00926 bool needs_members = true; 00927 CComObjPtr<IMgaFCO> fco; 00928 00929 deriv_type deriv; 00930 //ResolveDerivation(attributes, deriv); 00931 (*this.*m_resolveDerFuncPtr)(attributes, deriv); 00932 00933 if( GetPrevName() == _T("folder") ) 00934 { 00935 CComObjPtr<IMgaFolder> prev; 00936 GetPrevObj(prev); 00937 obj_prev = prev; 00938 00939 if( deriv.from != NULL ) 00940 { 00941 preparerelid(attributes); 00942 COMTHROW( prev->DeriveRootObject(deriv.from, deriv.isinstance, PutOut(fco)) ); 00943 assignrelid(fco); 00944 00945 // user info 00946 CComBSTR msg = makeLink( fco, makeNameViewable( GetByName(attributes, _T("closurename"))), true); 00947 COMTHROW(msg.Append( " set derived from ")); 00948 COMTHROW(msg.AppendBSTR( makeLink( deriv.from))); 00949 msgSC( msg, MSG_INFO); 00950 } 00951 else 00952 { 00953 // 'attributes' contains the id of the object (in the source project) 00954 bool found = findObject( prev, attributes, fco, 'S'); 00955 00956 // create only if not found 00957 if( !found) 00958 { 00959 CComObjPtr<IMgaMetaFCO> meta; 00960 COMTHROW( resolver->get_KindByStr(prev, PutInBstrAttr(attributes, _T("kind")), 00961 OBJTYPE_SET, PutOut(meta)) ); 00962 ASSERT( meta != NULL ); 00963 00964 preparerelid(attributes); 00965 COMTHROW( prev->CreateRootObject(meta, PutOut(fco)) ); 00966 assignrelid(fco); 00967 00968 // user info 00969 CComBSTR msg = makeLink( fco, makeNameViewable( GetByName(attributes, _T("closurename")))); 00970 COMTHROW(msg.Append( " set created.")); 00971 msgSC( msg, MSG_INFO); 00972 } 00973 else // will skip contained connpoints/elements/attribute values/regnode entries/constraints/name element 00974 { // will use the object found 00975 skip_inner_elements = true; 00976 //needs_members = isEmptySet( fco); //try to add to each set new members 00977 00978 // user info 00979 CComBSTR msg = "Merging "; 00980 COMTHROW(msg.AppendBSTR(makeLink( fco))); 00981 //if( needs_members) msg.Append(" empty"); 00982 COMTHROW(msg.Append( " set.")); 00983 msgSC( msg, MSG_INFO); 00984 } 00985 } 00986 } 00987 else 00988 { 00989 ASSERT( GetPrevName() == _T("model") ); 00990 00991 CComObjPtr<IMgaModel> prev; 00992 GetPrevObj(prev); 00993 obj_prev = prev; 00994 00995 CComObjPtr<IMgaMetaRole> role; 00996 COMTHROW( resolver->get_RoleByStr(prev, 00997 PutInBstrAttr(attributes, _T("kind")), OBJTYPE_SET, 00998 PutInBstrAttr(attributes, _T("role")), NULL, PutOut(role)) ); 00999 ASSERT( role != NULL ); 01000 01001 if( deriv.from != NULL ) 01002 { 01003 CComObjPtr<IMgaSet> derivedfrom; 01004 COMTHROW( deriv.from.QueryInterface(derivedfrom) ); 01005 01006 if( deriv.isprimary ) 01007 { 01008 preparerelid(attributes); 01009 COMTHROW( prev->DeriveChildObject(derivedfrom, role, deriv.isinstance, PutOut(fco)) ); 01010 assignrelid(fco); 01011 } 01012 else 01013 { 01014 preparerelid(attributes); 01015 COMTHROW( prev->get_ChildDerivedFrom(derivedfrom, PutOut(fco)) ); 01016 assignrelid(fco); 01017 } 01018 01019 // user info 01020 CComBSTR msg = makeLink( fco, makeNameViewable( GetByName(attributes, _T("closurename"))), true); 01021 COMTHROW(msg.Append( " set derived from ")); 01022 COMTHROW(msg.AppendBSTR( makeLink( deriv.from))); 01023 msgSC( msg, MSG_INFO); 01024 } 01025 else 01026 { 01027 // 'attributes' contains the id of the object (in the source project) 01028 bool found = findObject( prev, attributes, fco, 'S'); 01029 01030 // create only if not found 01031 if( !found) 01032 { 01033 preparerelid(attributes); 01034 COMTHROW( prev->CreateChildObject(role, PutOut(fco)) ); 01035 assignrelid(fco); 01036 01037 // user info 01038 CComBSTR msg = makeLink( fco, makeNameViewable( GetByName(attributes, _T("closurename")))); 01039 COMTHROW(msg.Append( " set created.")); 01040 msgSC( msg, MSG_INFO); 01041 } 01042 else // will skip contained connpoints/elements/attribute values/regnode entries/constraints/name element 01043 { // will use the object found 01044 skip_inner_elements = true; 01045 //needs_members = isEmptySet( fco); //try to add to each set new members 01046 01047 // user info 01048 CComBSTR msg = "Merging "; 01049 COMTHROW(msg.AppendBSTR(makeLink( fco))); 01050 //if( needs_members) msg.Append(" empty"); 01051 COMTHROW(msg.Append( " set.")); 01052 msgSC( msg, MSG_INFO); 01053 } 01054 } 01055 } 01056 ASSERT( fco != NULL ); 01057 01058 bool bound = GetByName(attributes, _T("isbound")) == _T("yes"); // if bound it does NOT need members added by hand 01059 if( needs_members && !bound) 01060 { 01061 std::list< CComObjPtr<IMgaFCO> > members;//slist 01062 01063 // mixed form is used in smartMemberGUIDs 01064 // i.e. {E200BEEB-34BC-4271-A134-AA5728C18124}\\/@../@module_ref1|kind=module_ref|relpos=0 01065 std::tstring combineds = GetByName(attributes, _T("smartMemberGUIDs")); 01066 std::list< std::tstring> combinedV = tokenizer( combineds, ' ', false); 01067 01068 // not needed currently, because the combined attr contains a series of <guid\\path>s 01069 //std::tstring paths = GetByName(attributes, _T("closure2members")); 01070 //std::list< std::tstring> nameV = tokenizer( paths, ' ', false); 01071 01072 std::list< std::tstring>::iterator li = combinedV.begin(); 01073 for( ; li != combinedV.end(); ++li) 01074 { 01075 CComObjPtr<IMgaFCO> mem; 01076 01077 std::tstring guid_s, path_s; 01078 if( (*li).size() >= GLOBAL_ID_LEN && (*li)[0] == '{' && (*li)[GLOBAL_ID_LEN-1] == '}' && (*li)[GLOBAL_ID_LEN] == '\\') // a guid form 01079 { 01080 guid_s = (*li).substr( 0, GLOBAL_ID_LEN); 01081 path_s = (*li).substr( GLOBAL_ID_LEN + 1); 01082 } 01083 else 01084 { 01085 guid_s = _T(""); 01086 path_s = *li; 01087 } 01088 01089 // search based on guid first, in the container only 01090 if( !guid_s.empty()) // guid not empty 01091 { 01092 findFCOWithGUID( obj_prev, guid_s, mem); 01093 } 01094 01095 // either no guid, or not found with guid -> in each case we have to search with path 01096 if( !mem) 01097 { 01098 CComObjPtr<IMgaObject> obj; 01099 findObjOnRelPath( CComObjPtr<IMgaObject>(fco), path_s, obj, _T("set member")); 01100 CComObjPtr<IMgaFCO> mem; 01101 if( obj) obj.QueryInterface( mem); 01102 } 01103 01104 // if element found, and is not found in the already found members container 01105 if( mem) 01106 { 01107 if( std::find( members.begin(), members.end(), mem) == members.end()) 01108 members.push_back( mem); 01109 } 01110 else 01111 { 01112 CComBSTR bstr( "Set "); 01113 COMTHROW(bstr.Append( makeLink( fco, makeNameViewable( GetByName(attributes, _T("closurename"))), true))); 01114 COMTHROW(bstr.Append( ": member not found. ")); 01115 COMTHROW(bstr.Append( "Search path used: ")); 01116 COMTHROW(bstr.Append( makeViewable( path_s).c_str())); 01117 msgSC(bstr, MSG_ERROR); 01118 01119 // insert data to process in 2nd step 01120 m_notFoundSetMembers[ fco ].push_back( path_s); 01121 } 01122 } 01123 01124 CComObjPtr<IMgaSet> mgaset; 01125 COMTHROW( fco.QueryInterface(mgaset) ); 01126 01127 //WAS: if( !(GetByName(attributes, _T("isbound")) == _T("yes")) ) { 01128 { 01129 COMTHROW( mgaset->RemoveAll() ); //by ZolMol: if not bound then the members are different, remove the inherited members 01130 std::list< CComObjPtr<IMgaFCO> >::iterator i = members.begin();//slist 01131 while( i != members.end() ) 01132 { 01133 COMTHROW( mgaset->AddMember(*i) ); 01134 ++i; 01135 } 01136 } 01137 } 01138 GetCurrent().object = fco; 01139 if( skip_inner_elements) 01140 GetCurrent().exstrinfo = _T("skip"); 01141 01142 RegisterLookup(attributes, fco); 01143 } 01144 01145 void CMgaParser::StartSCModel(const attributes_type &attributes) 01146 { 01147 bool skip_inner_elements = false; 01148 CComObjPtr<IMgaFCO> model; 01149 01150 deriv_type deriv; 01151 //ResolveDerivation(attributes, deriv); 01152 (*this.*m_resolveDerFuncPtr)(attributes, deriv); 01153 01154 01155 if( GetPrevName() == _T("folder") ) 01156 { 01157 CComObjPtr<IMgaFolder> prev; 01158 GetPrevObj(prev); 01159 01160 preparerelid(attributes); 01161 if( deriv.from != NULL ) 01162 { 01163 COMTHROW( prev->DeriveRootObject(deriv.from, deriv.isinstance, PutOut(model)) ); 01164 01165 // user info 01166 CComBSTR msg = makeLink( model, makeNameViewable( GetByName(attributes, _T("closurename"))), true); 01167 COMTHROW(msg.Append( " model derived from ")); 01168 COMTHROW(msg.AppendBSTR( makeLink( deriv.from))); 01169 msgSC( msg, MSG_INFO); 01170 } 01171 else 01172 { 01173 // 'attributes' contains the id of the object (in the source project) 01174 bool found = findObject( prev, attributes, model, 'M'); 01175 01176 // create only if not found 01177 if( !found) 01178 { 01179 CComObjPtr<IMgaMetaFCO> meta; 01180 COMTHROW( resolver->get_KindByStr(prev, PutInBstrAttr(attributes, _T("kind")), 01181 OBJTYPE_MODEL, PutOut(meta)) ); 01182 ASSERT( meta != NULL ); 01183 01184 COMTHROW( prev->CreateRootObject(meta, PutOut(model)) ); 01185 01186 // user info 01187 CComBSTR msg = makeLink( model, makeNameViewable( GetByName(attributes, _T("closurename")))); 01188 COMTHROW(msg.Append( " model created.")); 01189 msgSC( msg, MSG_INFO); 01190 } 01191 else // will use the object found 01192 { // will skip contained elements/attribute values/regnode entries/constraints/name element 01193 skip_inner_elements = true; 01194 01195 // user info 01196 CComBSTR msg = "Merging "; 01197 COMTHROW(msg.AppendBSTR(makeLink( model))); 01198 COMTHROW(msg.Append( " model.")); 01199 msgSC( msg, MSG_INFO); 01200 } 01201 } 01202 assignrelid(model); 01203 } 01204 else 01205 { 01206 ASSERT( GetPrevName() == _T("model") ); 01207 01208 CComObjPtr<IMgaModel> prev; 01209 GetPrevObj(prev); 01210 01211 CComObjPtr<IMgaMetaRole> role; 01212 COMTHROW( resolver->get_RoleByStr(prev, 01213 PutInBstrAttr(attributes, _T("kind")), OBJTYPE_MODEL, 01214 PutInBstrAttr(attributes, _T("role")), NULL, PutOut(role)) ); 01215 ASSERT( role != NULL ); 01216 01217 if( deriv.from != NULL ) 01218 { 01219 CComObjPtr<IMgaModel> derivedfrom; 01220 COMTHROW( deriv.from.QueryInterface(derivedfrom) ); 01221 01222 if( deriv.isprimary ) 01223 { 01224 preparerelid(attributes); 01225 COMTHROW( prev->DeriveChildObject(derivedfrom, role, deriv.isinstance, PutOut(model)) ); 01226 assignrelid(model); 01227 } 01228 else 01229 { 01230 COMTHROW( prev->get_ChildDerivedFrom(derivedfrom, PutOut(model)) ); 01231 } 01232 01233 // user info 01234 CComBSTR msg = makeLink( model, makeNameViewable( GetByName(attributes, _T("closurename"))), true); 01235 COMTHROW(msg.Append( " model derived from ")); 01236 COMTHROW(msg.AppendBSTR( makeLink( deriv.from))); 01237 msgSC( msg, MSG_INFO); 01238 } 01239 else 01240 { 01241 // 'attributes' contains the id of the object (in the source project) 01242 bool found = findObject( prev, attributes, model, 'M'); 01243 01244 // create only if not found 01245 if( !found) 01246 { 01247 preparerelid(attributes); 01248 COMTHROW( prev->CreateChildObject(role, PutOut(model)) ); 01249 assignrelid(model); 01250 01251 // user info 01252 CComBSTR msg = makeLink( model, makeNameViewable( GetByName(attributes, _T("closurename")))); 01253 COMTHROW(msg.Append( " model created.")); 01254 msgSC( msg, MSG_INFO); 01255 } 01256 else // will use the object found 01257 { 01258 skip_inner_elements = true; 01259 01260 // user info 01261 CComBSTR msg = "Merging "; 01262 COMTHROW(msg.AppendBSTR(makeLink( model))); 01263 COMTHROW(msg.Append( " model.")); 01264 msgSC( msg, MSG_INFO); 01265 } 01266 } 01267 } 01268 ASSERT( model != NULL ); 01269 01270 GetCurrent().object = model; 01271 long crid = toLong(GetByName(attributes,_T("childrelidcntr"))); 01272 GetCurrent().exnuminfo = crid; 01273 // model may not be IMgaModel if "merging" (FIXME: likely a bug elsewhere) (crash e72e1106-8ab3-42af-b0e7-087fbef92b19) 01274 COMTHROW(CComQIPtr<IMgaModel>(model) ? CComQIPtr<IMgaModel>(model)->put_ChildRelIDCounter(crid) : S_OK); 01275 01276 if( skip_inner_elements) 01277 GetCurrent().exstrinfo = _T("skip"); 01278 01279 RegisterLookup(attributes, model); 01280 } 01281 01282 void CMgaParser::StartSCAtom(const attributes_type &attributes) 01283 { 01284 bool skip_inner_elements = false; 01285 CComObjPtr<IMgaFCO> atom; 01286 01287 deriv_type deriv; 01288 //ResolveDerivation(attributes, deriv); 01289 (*this.*m_resolveDerFuncPtr)(attributes, deriv); 01290 01291 if( GetPrevName() == _T("folder") ) 01292 { 01293 CComObjPtr<IMgaFolder> prev; 01294 GetPrevObj(prev); 01295 01296 if( deriv.from != NULL ) 01297 { 01298 COMTHROW( prev->DeriveRootObject(deriv.from, deriv.isinstance, PutOut(atom)) ); 01299 01300 // user info 01301 CComBSTR msg = makeLink( atom, makeNameViewable( GetByName(attributes, _T("closurename"))), true); 01302 COMTHROW(msg.Append( " atom derived from ")); 01303 COMTHROW(msg.AppendBSTR( makeLink( deriv.from))); 01304 msgSC( msg, MSG_INFO); 01305 } 01306 else 01307 { 01308 // 'attributes' contains the id of the object (in the source project) 01309 bool found = findObject( prev, attributes, atom, 'A'); 01310 01311 // create only if not found 01312 if( !found) 01313 { 01314 CComObjPtr<IMgaMetaFCO> meta; 01315 COMTHROW( resolver->get_KindByStr(prev, PutInBstrAttr(attributes, _T("kind")), 01316 OBJTYPE_ATOM, PutOut(meta)) ); 01317 ASSERT( meta != NULL ); 01318 01319 preparerelid(attributes); 01320 COMTHROW( prev->CreateRootObject(meta, PutOut(atom)) ); 01321 assignrelid(atom); 01322 01323 // user info 01324 CComBSTR msg = makeLink( atom, makeNameViewable( GetByName(attributes, _T("closurename")))); 01325 COMTHROW(msg.Append( L" atom created.")); 01326 msgSC( msg, MSG_INFO); 01327 } 01328 else // will use the object found 01329 { 01330 skip_inner_elements = true; 01331 01332 // user info 01333 CComBSTR msg = L"Merging "; 01334 COMTHROW(msg.AppendBSTR(makeLink( atom))); 01335 COMTHROW(msg.Append( L" atom.")); 01336 msgSC( msg, MSG_INFO); 01337 } 01338 } 01339 } 01340 else 01341 { 01342 ASSERT( GetPrevName() == _T("model") ); 01343 01344 CComObjPtr<IMgaModel> prev; 01345 GetPrevObj(prev); 01346 01347 CComObjPtr<IMgaMetaRole> role; 01348 COMTHROW( resolver->get_RoleByStr(prev, 01349 PutInBstrAttr(attributes, _T("kind")), OBJTYPE_ATOM, 01350 PutInBstrAttr(attributes, _T("role")), NULL, PutOut(role)) ); 01351 ASSERT( role != NULL ); 01352 01353 if( deriv.from != NULL ) 01354 { 01355 CComObjPtr<IMgaAtom> derivedfrom; 01356 COMTHROW( deriv.from.QueryInterface(derivedfrom) ); 01357 01358 if( deriv.isprimary ) 01359 { 01360 preparerelid(attributes); 01361 COMTHROW( prev->DeriveChildObject(derivedfrom, role, deriv.isinstance, PutOut(atom)) ); 01362 assignrelid(atom); 01363 } 01364 else 01365 { 01366 COMTHROW( prev->get_ChildDerivedFrom(derivedfrom, PutOut(atom)) ); 01367 } 01368 01369 // user info 01370 CComBSTR msg = makeLink( atom, makeNameViewable( GetByName(attributes, _T("closurename"))), true); 01371 COMTHROW(msg.Append( L" atom derived from ")); 01372 COMTHROW(msg.AppendBSTR( makeLink( deriv.from))); 01373 msgSC( msg, MSG_INFO); 01374 } 01375 else 01376 { 01377 // 'attributes' contains the id of the object (in the source project) 01378 bool found = findObject( prev, attributes, atom, 'A'); 01379 if( !found) 01380 { 01381 // create only if not found 01382 preparerelid(attributes); 01383 COMTHROW( prev->CreateChildObject(role, PutOut(atom)) ); 01384 assignrelid(atom); 01385 01386 // user info 01387 CComBSTR msg = makeLink( atom, makeNameViewable( GetByName(attributes, _T("closurename")))); 01388 COMTHROW(msg.Append( L" atom created.")); 01389 msgSC( msg, MSG_INFO); 01390 } 01391 else // will skip contained elements 01392 { 01393 skip_inner_elements = true; 01394 01395 // user info 01396 CComBSTR msg = L"Merging "; 01397 COMTHROW(msg.AppendBSTR(makeLink( atom))); 01398 COMTHROW(msg.Append( L" atom.")); 01399 msgSC( msg, MSG_INFO); 01400 } 01401 } 01402 } 01403 01404 ASSERT( atom != NULL ); 01405 GetCurrent().object = atom; 01406 01407 if( skip_inner_elements) 01408 GetCurrent().exstrinfo = _T("skip"); 01409 01410 RegisterLookup(attributes, atom); 01411 } 01412 01413 void CMgaParser::StartSCFolder(const attributes_type &attributes) 01414 { 01415 bool skip_inner_elements = false; 01416 CComObjPtr<IMgaFolder> folder; 01417 01418 //if( GetPrevName() == _T("project") ) 01419 //{ 01420 // COMTHROW( project->get_RootFolder(PutOut(folder)) ); 01421 //} 01422 //else 01423 { 01424 CComObjPtr<IMgaFolder> prev; 01425 GetPrevObj(prev); 01426 01427 CComObjPtr<IMgaMetaFolder> meta; 01428 _bstr_t fname(PutInBstrAttr(attributes, _T("kind"))); 01429 01430 VARIANT_BOOL previactmode; 01431 COMTHROW(resolver->get_IsInteractive(&previactmode)); 01432 COMTHROW(resolver->put_IsInteractive(VARIANT_FALSE)); 01433 HRESULT hr = resolver->get_FolderByStr(prev, fname, PutOut(meta)); 01434 COMTHROW(resolver->put_IsInteractive(previactmode)); 01435 01436 ASSERT(meta); 01437 01438 // 01439 bool found = findFolderIn( prev, attributes, folder); 01440 01441 // create only if not found 01442 if( !found) 01443 { 01444 preparerelid(attributes); 01445 COMTHROW( prev->CreateFolder(meta, PutOut(folder))); 01446 assignrelid(folder); 01447 01448 // user info 01449 CComBSTR msg = makeLink(CComObjPtr<IMgaObject>(folder), makeNameViewable( GetByName(attributes, _T("closurename")))); 01450 COMTHROW(msg.Append(L" folder created.")); 01451 msgSC( msg, MSG_INFO); 01452 } 01453 else // will use the object found 01454 { 01455 skip_inner_elements = true; 01456 01457 // user info 01458 CComBSTR msg = L"Merging "; 01459 COMTHROW(msg.AppendBSTR(makeLink( CComObjPtr<IMgaObject>(folder)))); 01460 COMTHROW(msg.Append( L" folder.")); 01461 msgSC( msg, MSG_INFO); 01462 } 01463 } 01464 ASSERT( folder != NULL ); 01465 GetCurrent().object = folder; 01466 if( skip_inner_elements) 01467 GetCurrent().exstrinfo = _T("skip"); 01468 01469 long crid = toLong(GetByName(attributes,_T("childrelidcntr"))); 01470 GetCurrent().exnuminfo = crid; 01471 COMTHROW(folder->put_ChildRelIDCounter(crid)); 01472 01473 RegisterLookup(attributes, folder); 01474 } 01475 01476 void CMgaParser::StartSCRegNode(const attributes_type &attributes) 01477 { 01478 CComObjPtr<IMgaRegNode> regnode; 01479 01480 _bstr_t name = GetByName(attributes, _T("name")).c_str(); 01481 01482 if( GetPrevName() == _T("regnode") ) 01483 { 01484 CComObjPtr<IMgaRegNode> prev; 01485 GetPrevObj(prev); 01486 01487 COMTHROW( prev->get_SubNodeByName(name, PutOut(regnode)) ); 01488 } 01489 else if( GetPrevName() == _T("folder") ) 01490 { 01491 CComObjPtr<IMgaFolder> prev; 01492 GetPrevObj(prev); 01493 01494 COMTHROW( prev->get_RegistryNode(name, PutOut(regnode)) ); 01495 } 01496 else if( GetPrevName() == _T("attribute") ) 01497 { 01498 CComObjPtr<IMgaAttribute> prev; 01499 GetPrevObj(prev); 01500 01501 COMTHROW( prev->get_RegistryNode(name, PutOut(regnode)) ); 01502 } 01503 else 01504 { 01505 CComObjPtr<IMgaFCO> prev; 01506 GetPrevObj(prev); 01507 01508 COMTHROW( prev->get_RegistryNode(name, PutOut(regnode)) ); 01509 } 01510 ASSERT( regnode != NULL ); 01511 01512 // check its status 01513 long st; 01514 COMTHROW( regnode->get_Status( &st)); 01515 01516 // if MERGE case (skip) and if value is defined HERE, then skip it (don't touch) its value 01517 // but the subnodes may change! even in this case if UNDEF, or they may be created if they not exist 01518 if( GetPrevious().exstrinfo == _T("skip") && st == ATTSTATUS_HERE) 01519 { 01520 GetCurrent().exstrinfo = _T("skip"); // might have subelements so skip those as well 01521 GetCurrent().object = regnode; 01522 return; 01523 } 01524 01525 if( GetByNameX(attributes, _T("status")) == NULL ) 01526 COMTHROW( regnode->put_Value(NULL) ); 01527 01528 if( GetByName(attributes, _T("isopaque")) == _T("yes") ) 01529 COMTHROW( regnode->put_Opacity(VARIANT_TRUE) ); 01530 01531 GetCurrent().object = regnode; 01532 } 01533 01534 void CMgaParser::EndSCRegNode() 01535 { 01536 if( GetPrevious().exstrinfo == _T("skip")) // if merge return, deal only with new regnodes 01537 return; 01538 01539 CComObjPtr<IMgaRegNode> fresh_regnode; 01540 01541 ASSERT( GetCurrent().object); 01542 COMTHROW( GetCurrent().object.QueryInterface( fresh_regnode)); 01543 if( !fresh_regnode) return; 01544 01545 01546 // responsible for shifting the guid related regnodes: 01547 // guid goes to guid/prev node 01548 // new guid to be created int guid node 01549 01550 CComBSTR nm; 01551 COMTHROW( fresh_regnode->get_Name( &nm)); 01552 01553 if( nm != GLOBAL_ID_STR) 01554 return; 01555 01556 long status; 01557 COMTHROW( fresh_regnode->get_Status( &status)); 01558 01559 if( status != 0) // guid NOT defined here 01560 return; 01561 01562 CComBSTR guid; 01563 // guid in the old project 01564 COMTHROW( fresh_regnode->get_Value( &guid)); 01565 01566 // replace the old GUID with a new one 01567 COMTHROW( fresh_regnode->put_Value( GuidCreate::newGuid())); 01568 01569 if( guid.Length() != GLOBAL_ID_LEN) // guid invalid, do not store it in prev subnode 01570 return; 01571 01572 // store the old GUID in 'prev' subnode 01573 CComPtr<IMgaRegNode> subnd; 01574 COMTHROW( fresh_regnode->get_SubNodeByName( CComBSTR(PREV_ID_STR), &subnd)); 01575 01576 if( subnd) COMTHROW( subnd->put_Value(guid) ); 01577 01578 } 01579 01580 void CMgaParser::StartSCAttribute(const attributes_type &attributes) 01581 { 01582 CComObjPtr<IMgaAttribute> attr; 01583 01584 CComObjPtr<IMgaFCO> fco; 01585 GetPrevObj(fco); 01586 01587 CComObjPtr<IMgaMetaAttribute> metaattr; 01588 HRESULT hr = resolver->get_AttrByStr(fco, PutInBstrAttr(attributes, _T("kind")), PutOut(metaattr)); 01589 01590 if( FAILED(hr) || metaattr == NULL ) 01591 { 01592 GetCurrent().object = NULL; 01593 return; 01594 } 01595 01596 COMTHROW( fco->get_Attribute(metaattr, PutOut(attr)) ); 01597 01598 ASSERT( attr != NULL ); 01599 GetCurrent().object = attr; 01600 01601 long st; // check its status: if value is defined HERE, then skip it (don't touch) 01602 COMTHROW( attr->get_Status( &st)); 01603 01604 // in case parent is merged (skipped) and attr is defined HERE, skip inner contents: 01605 if( GetPrevious().exstrinfo == _T("skip") && st == ATTSTATUS_HERE) 01606 { 01607 GetCurrent().exstrinfo = _T("skip"); // might have subelements so skip those as well 01608 return; 01609 } 01610 01611 if( GetByNameX(attributes, _T("status")) == NULL ) 01612 { 01613 // we set some value, and from the "value" element we set the actual value 01614 01615 CComVariant v; 01616 COMTHROW( attr->get_Value(PutOut(v)) ); 01617 COMTHROW( attr->put_Value(v) ); 01618 } 01619 } 01620 01621 void CMgaParser::EndSCName() 01622 { 01623 if( GetPrevious().exstrinfo == _T("skip")) // has no sub elements 01624 return; 01625 01626 //if( GetPrevName() == _T("project") ) 01627 //{ 01628 // COMTHROW( project->put_Name(PutInBstr(GetCurrData())) ); 01629 //} 01630 //else 01631 if( GetPrevName() == _T("constraint") ) 01632 { 01633 constraint_name = GetCurrData(); 01634 } 01635 else if( GetPrevious().object != NULL ) 01636 { 01637 CComObjPtr<IMgaObject> prev; 01638 GetPrevObj(prev); 01639 COMTHROW( prev->put_Name(PutInBstr(GetCurrData())) ); 01640 } 01641 } 01642 01643 void CMgaParser::EndSCValue() 01644 { 01645 if( GetPrevious().exstrinfo == _T("skip")) // has no sub elements 01646 return; 01647 01648 // skip if the object is ignored 01649 if( GetPrevious().object == NULL ) 01650 return; 01651 01652 if( GetPrevName() == _T("constraint") ) 01653 { 01654 constraint_value = GetCurrData(); 01655 } 01656 else 01657 if( GetPrevName() == _T("regnode") ) 01658 { 01659 CComObjPtr<IMgaRegNode> regnode; 01660 GetPrevObj(regnode); 01661 01662 long status; 01663 COMTHROW( regnode->get_Status(&status) ); 01664 01665 // when we create the registry node, 01666 // we fill it by an empty string if not inherited or not undefined 01667 if( status == 0) 01668 COMTHROW( regnode->put_Value(PutInBstr(GetCurrData())) ); 01669 } 01670 else if( GetPrevName() == _T("attribute") ) 01671 { 01672 CComObjPtr<IMgaAttribute> attr; 01673 GetPrevObj(attr); 01674 01675 long status; 01676 COMTHROW( attr->get_Status(&status) ); 01677 01678 // if inherited, then do not modify the value 01679 if( status != 0 ) 01680 return; 01681 01682 CComObjPtr<IMgaMetaAttribute> metaattr; 01683 COMTHROW( attr->get_Meta(PutOut(metaattr)) ); 01684 ASSERT( metaattr != NULL ); 01685 01686 attval_enum attval; 01687 COMTHROW( metaattr->get_ValueType(&attval) ); 01688 01689 CComVariant v; 01690 01691 switch( attval ) 01692 { 01693 case ATTVAL_STRING: 01694 case ATTVAL_ENUM: 01695 case ATTVAL_DYNAMIC: 01696 v = GetCurrData().c_str(); 01697 break; 01698 01699 case ATTVAL_INTEGER: 01700 v = GetCurrData().c_str(); 01701 COMTHROW( v.ChangeType(VT_I4) ); 01702 break; 01703 01704 case ATTVAL_DOUBLE: 01705 v = GetCurrData().c_str(); 01706 COMTHROW( v.ChangeType(VT_R8) ); 01707 break; 01708 01709 case ATTVAL_BOOLEAN: 01710 { 01711 char c = tolower(*GetCurrData().c_str()); 01712 CopyTo( (c == 't' || c == '1' || c == 'y') ? VARIANT_TRUE : VARIANT_FALSE, v); 01713 break; 01714 } 01715 01716 case ATTVAL_REFERENCE: 01717 { 01718 CComObjPtr<IMgaFCO> object; 01719 LookupByID(GetCurrData(), object); 01720 01721 if( object == NULL ) 01722 throw pass_exception(); 01723 01724 CopyTo(object, v); 01725 } 01726 01727 default: 01728 HR_THROW(E_INVALID_META); 01729 01730 }; 01731 01732 COMTHROW( attr->put_Value(v) ); 01733 } 01734 } 01735 01736 void CMgaParser::EndSCConstraint() 01737 { 01738 if( GetPrevious().exstrinfo == _T("skip")) 01739 { 01740 GetCurrent().exstrinfo = _T("skip"); // might have subelements, so skip those as well 01741 return; 01742 } 01743 01744 CComObjPtr<IMgaConstraint> constraint; 01745 01746 if( GetPrevName() == _T("folder") ) 01747 { 01748 CComObjPtr<IMgaFolder> folder; 01749 GetPrevObj(folder); 01750 01751 COMTHROW( folder->DefineConstraint(PutInBstr(constraint_name), 0, // FIXME: the mask 01752 PutInBstr(constraint_value), PutOut(constraint)) ); 01753 } 01754 else 01755 { 01756 CComObjPtr<IMgaFCO> fco; 01757 GetPrevObj(fco); 01758 01759 COMTHROW( fco->DefineConstraint(PutInBstr(constraint_name), 0, // FIXME: the mask 01760 PutInBstr(constraint_value), PutOut(constraint)) ); 01761 } 01762 } 01763 01764