GME
13
|
00001 00002 #include "stdafx.h" 00003 #include "Parser.h" 00004 #include "MgaDumper.h" 00005 #include "Transcoder.h" 00006 #include <algorithm> 00007 00008 #define FLUSH_LIMIT 1000 00009 00010 // ----------------------------------------------------------- 00011 // --------------------------- GmeEqual ---------------------- 00012 // ----------------------------------------------------------- 00013 GmeEqual::GmeEqual( CComObjPtr<IMgaObject> obj) 00014 : m_objToFind( obj), m_which( 1) 00015 { } 00016 00017 00018 GmeEqual::GmeEqual( CComObjPtr<IMgaFCO> fco) 00019 : m_fcoToFind( fco), m_which( 2) 00020 { } 00021 00022 00023 GmeEqual::GmeEqual( CComObjPtr<IMgaFolder> folder) 00024 : m_folderToFind( folder), m_which( 3) 00025 { } 00026 00027 00028 GmeEqual::GmeEqual( CComObjPtr<IMgaModel> model) 00029 : m_modelToFind( model), m_which( 4) 00030 { } 00031 00032 00033 bool GmeEqual::operator() ( CComObjPtr<IMgaObject>& op ) 00034 { 00035 ASSERT( m_which == 1); // which variable is set 00036 00037 VARIANT_BOOL is_equal; 00038 COMTHROW( m_objToFind->get_IsEqual( op, &is_equal)); 00039 00040 if (is_equal != VARIANT_FALSE) 00041 return true; 00042 00043 return false; 00044 } 00045 00046 bool GmeEqual::operator() ( CComObjPtr<IMgaFCO>& op ) 00047 { 00048 ASSERT( m_which == 2); // which variable is set 00049 00050 VARIANT_BOOL is_equal; 00051 COMTHROW( m_fcoToFind->get_IsEqual( op, &is_equal)); 00052 00053 if (is_equal != VARIANT_FALSE) 00054 return true; 00055 00056 return false; 00057 } 00058 00059 bool GmeEqual::operator() ( CComObjPtr<IMgaFolder>& op ) 00060 { 00061 ASSERT( m_which == 3); // which variable is set 00062 00063 VARIANT_BOOL is_equal; 00064 COMTHROW( m_folderToFind->get_IsEqual( op, &is_equal)); 00065 00066 if (is_equal != VARIANT_FALSE) 00067 return true; 00068 00069 return false; 00070 } 00071 00072 bool GmeEqual::operator() ( CComObjPtr<IMgaModel>& op ) 00073 { 00074 ASSERT( m_which == 4); // which variable is set 00075 00076 VARIANT_BOOL is_equal; 00077 COMTHROW( m_modelToFind->get_IsEqual( op, &is_equal)); 00078 00079 if (is_equal != VARIANT_FALSE) 00080 return true; 00081 00082 return false; 00083 } 00084 00085 00086 // --------------------------- CMgaDumper 00087 00088 void CMgaDumper::InitDump(IMgaProject *p, BSTR xmlfile, BSTR encoding) 00089 { 00090 if( p == NULL ) 00091 HR_THROW(E_INVALIDARG); 00092 00093 std::tstring filename; 00094 CopyTo(xmlfile, filename); 00095 00096 if( filename.empty() ) 00097 HR_THROW(E_INVALIDARG); 00098 00099 ofs.init( filename.c_str(), encoding); 00100 00101 elems.clear(); 00102 00103 ASSERT( project == NULL ); 00104 ASSERT( territory == NULL ); 00105 00106 territory = NULL; 00107 COMTHROW( p->CreateTerritory(NULL, PutOut(territory), NULL) ); 00108 00109 COMTHROW( p->BeginTransaction(territory, TRANSACTION_READ_ONLY) ); 00110 project = p; 00111 00112 fco_count = 0; 00113 } 00114 00115 void CMgaDumper::DoneDump(bool abort) 00116 { 00117 ofs.finalize(); 00118 elems.clear(); 00119 00120 if( territory != NULL ) 00121 COMTHROW(territory->Destroy()); 00122 territory = NULL; 00123 00124 if( project != NULL ) 00125 { 00126 if( abort ) 00127 COMTHROW(project->AbortTransaction()); 00128 else 00129 COMTHROW(project->CommitTransaction()); 00130 } 00131 00132 m_selFcos.clear(); 00133 m_selFolders.clear(); 00134 project = NULL; 00135 } 00136 00137 STDMETHODIMP CMgaDumper::DumpProject(IMgaProject *p, BSTR xmlfile) 00138 { 00139 return DumpProject2(p, xmlfile, NULL); 00140 } 00141 00142 STDMETHODIMP CMgaDumper::DumpProject2(IMgaProject *p, BSTR xmlfile, ULONGLONG hwndParent_) 00143 { 00144 CHECK_IN(p); 00145 m_dumpGuids = true; // dump GUIDs with the whole project 00146 m_closureDump = false; 00147 m_v2 = false; 00148 m_strictDump = false; 00149 m_dumpRelids = true; 00150 m_dumpLibraryStubs = false; // make sure closure logic does not involve in it 00151 00152 COMTRY 00153 { 00154 HWND hwndParent = (HWND)hwndParent_; 00155 if (hwndParent != 0) 00156 { 00157 COMTHROW( m_progress.CoCreateInstance(L"Mga.MgaProgressDlg") ); 00158 COMTHROW( m_progress->SetTitle(_bstr_t(L"Exporting XME file...")) ); 00159 COMTHROW( m_progress->StartProgressDialog(hwndParent) ); 00160 } 00161 InitDump(p, xmlfile, _bstr_t(L"UTF-8")); 00162 00163 ofs << L"<!DOCTYPE project SYSTEM \"mga.dtd\">\n\n"; 00164 00165 Dump(p); 00166 00167 DoneDump(false); 00168 if (m_progress != NULL ) 00169 { 00170 COMTHROW(m_progress->StopProgressDialog()); 00171 m_progress = NULL; 00172 } 00173 } 00174 COMCATCH( 00175 DoneDump(true); 00176 if (m_progress != NULL ) 00177 { 00178 COMTHROW(m_progress->StopProgressDialog()); 00179 m_progress = NULL; 00180 } 00181 ) 00182 } 00183 00184 STDMETHODIMP CMgaDumper::DumpFCOs(IMgaProject *proj, IMgaFCOs *p, IMgaFolders *f, IMgaRegNodes *r, BSTR xmlfile) 00185 { 00186 return DumpFCOs2(proj, p, f, r, xmlfile, NULL); 00187 } 00188 00189 STDMETHODIMP CMgaDumper::DumpFCOs2(IMgaProject *proj, IMgaFCOs *p, IMgaFolders *f, IMgaRegNodes *r, BSTR xmlfile, ULONGLONG hwndParent) 00190 { 00191 m_dumpGuids = false; // while dumping selected FCOs do NOT dump guids of the fco's 00192 m_closureDump = false; 00193 m_v2 = false; 00194 m_strictDump = false; // this method uses the permissive dump 00195 // meaning that if a model/folder is in the closure then all children 00196 // and grandchildren are dumped as well 00197 00198 m_dumpRelids = false; //dumpversion = 2; // no relids dumped 00199 m_dumpLibraryStubs = false; // make sure closure logic does not involve in it 00200 00201 //CHECK_IN( (int)p | (int)f); 00202 00203 COMTRY 00204 { 00205 if ( p) CopyTo(p, m_selFcos); 00206 if ( f) CopyTo(f, m_selFolders); 00207 if ( r) CopyTo(r, m_selRegNodes); 00208 00209 if( m_selFcos.empty() && m_selFolders.empty() && m_selRegNodes.empty()) 00210 return S_OK; 00211 00212 CComObjPtr<IMgaProject> project; 00213 00214 if ( !m_selFcos.empty()) 00215 COMTHROW( m_selFcos.front()->get_Project( PutOut( project)) ); 00216 else if ( !m_selFolders.empty()) 00217 COMTHROW( m_selFolders.front()->get_Project( PutOut( project)) ); 00218 else if ( !m_selRegNodes.empty()) // newly added 00219 project = proj; 00220 else 00221 return S_OK; 00222 00223 if( !project) return S_OK; 00224 00225 InitDump(project, xmlfile, _bstr_t(L"UTF-16")); 00226 00227 ofs << L"<!DOCTYPE clipboard SYSTEM \"mga.dtd\" [\r\n"; 00228 ofs << L"\t<!ELEMENT clipboard (folder|model|atom|reference|set|connection|regnode)*>\r\n"; 00229 //ofs << "\t<!ATTLIST clipboard acceptingkind CDATA #IMPLIED>\n"; 00230 //ofs << "]>\n\n"; 00231 ofs << L"\t<!ATTLIST clipboard\r\n"; 00232 ofs << L"\t\tacceptingkind CDATA #IMPLIED\r\n"; 00233 ofs << L"\t\tparadigmnamehint CDATA #IMPLIED\r\n";//TODO: could be extended with targetnamespacehint, srcnamespacehint 00234 ofs << L"\t>\r\n"; 00235 ofs << L"]>\r\n\r\n"; 00236 00237 00238 00239 StartElem(_T("clipboard")); 00240 00241 // dumping originating paradigm name as a hint for the parser 00242 CComObjPtr<IMgaMetaProject> metaproject; 00243 COMTHROW( project->get_RootMeta(PutOut(metaproject)) ); 00244 ASSERT( metaproject != NULL ); 00245 if( metaproject) Attr(_T("paradigmnamehint"), metaproject, &IMgaMetaProject::get_Name); 00246 00247 CComObjPtrVector<IMgaFolder>::iterator fi = m_selFolders.begin(); 00248 while( fi != m_selFolders.end() ) 00249 { 00250 CComObjPtr<IMgaObject> obj; 00251 COMTHROW(territory->OpenObj(*fi, PutOut(obj))); 00252 CComObjPtr<IMgaFolder> folder; 00253 COMTHROW(obj.QueryInterface( folder)); 00254 *fi = folder; 00255 ++fi; 00256 } 00257 00258 CComObjPtrVector<IMgaFCO>::iterator i = m_selFcos.begin(); 00259 while( i != m_selFcos.end() ) 00260 { 00261 // PETER: put the object into the parser's territory 00262 CComObjPtr<IMgaObject> obj; 00263 COMTHROW(territory->OpenObj(*i, PutOut(obj))); 00264 CComObjPtr<IMgaFCO> fco; 00265 COMTHROW(obj.QueryInterface( fco)); 00266 *i = fco; 00267 ++i; 00268 } 00269 00270 if( m_selFolders.size() + m_selFcos.size() > 0) removeInnerObjs(); 00271 00272 for( fi = m_selFolders.begin(); fi != m_selFolders.end(); ++fi ) 00273 Dump( *fi); 00274 00275 for( i = m_selFcos.begin(); i != m_selFcos.end(); ++i ) 00276 Dump ( *i); 00277 00278 if( !m_selRegNodes.empty()) 00279 { 00280 StartElem(_T("regnode")); 00281 Attr(_T("name"), _T("annotations")); 00282 StartElem(_T("value")); 00283 EndElem(); //value 00284 00285 for( CComObjPtrVector<IMgaRegNode>::iterator ri = m_selRegNodes.begin(); ri != m_selRegNodes.end(); ++ri) 00286 Dump( *ri); 00287 00288 EndElem(); // regnode of annotations 00289 } 00290 00291 EndElem(); 00292 DoneDump(false); 00293 } 00294 COMCATCH( DoneDump(true); ) 00295 } 00296 00297 // ------- Low level stuff 00298 00299 inline void CMgaDumper::Indent(int i) 00300 { 00301 for(; i > 0; --i) 00302 ofs << '\t'; 00303 } 00304 00305 inline void CMgaDumper::StartElem(const TCHAR *name) 00306 { 00307 ASSERT( name != NULL ); 00308 00309 if( !elems.empty() && !elems.back().inbody ) 00310 { 00311 ASSERT( !elems.back().indata ); 00312 00313 ofs << L">\n"; 00314 elems.back().inbody = true; 00315 } 00316 00317 elems.push_back(elem()); 00318 elems.back().name = name; 00319 elems.back().inbody = false; 00320 elems.back().indata = false; 00321 00322 Indent(elems.size()-1); 00323 ofs << L'<' << name; 00324 } 00325 00326 inline void CMgaDumper::Attr(const TCHAR *name, const TCHAR *value) 00327 { 00328 ASSERT( name != NULL ); 00329 ASSERT( value != NULL ); 00330 00331 ASSERT( !elems.empty() && !elems.back().inbody ); 00332 00333 ofs << L' ' << name << L"=\"" << Transcoder::StdEscape << value << Transcoder::NoEscape << L'"'; 00334 } 00335 00336 inline void CMgaDumper::Attr(const TCHAR *name, const TCHAR *value, int len) 00337 { 00338 ASSERT( name != NULL ); 00339 ASSERT( value != NULL ); 00340 ASSERT( len >= 0 ); 00341 00342 ASSERT( !elems.empty() && !elems.back().inbody && !elems.back().indata ); 00343 00344 ofs << L' ' << name << L"=\"" << Transcoder::StdEscape << std::tstring( value, len) << Transcoder::NoEscape << L'"'; 00345 } 00346 00347 bool CMgaDumper::HasMarkup(const TCHAR *value, int len) 00348 { 00349 while( --len >= 0 ) 00350 { 00351 TCHAR c = *(value++); 00352 if( c == '<' || c == '>' || c == '&' || c == '\'' || c == '\"' ) 00353 return true; 00354 } 00355 00356 return false; 00357 } 00358 00359 inline void CMgaDumper::Data(const TCHAR *value, int len) 00360 { 00361 ASSERT( value != NULL ); 00362 ASSERT( len >= 0 ); 00363 ASSERT( !elems.empty() ); 00364 00365 if( !elems.back().inbody ) 00366 { 00367 ofs << L">"; 00368 elems.back().inbody = true; 00369 } 00370 00371 ofs << Transcoder::StdEscape << std::tstring( value, len) << Transcoder::NoEscape; 00372 00373 elems.back().indata = true; 00374 00375 } 00376 00377 inline void CMgaDumper::EndElem() 00378 { 00379 ASSERT( !elems.empty() ); 00380 00381 if( elems.back().inbody ) 00382 { 00383 if( !elems.back().indata ) 00384 Indent(elems.size()-1); 00385 00386 ofs << L"</" << elems.back().name << L">\n"; 00387 } 00388 else 00389 { 00390 ofs << L"/>\n"; 00391 } 00392 00393 elems.pop_back(); 00394 } 00395 00396 // ------- CheckInClosure 00397 // there are two ways: 00398 // strict: those objects are dumped which are selected ( can be found in m_selFCO/Folder) 00399 // this method is used by the copy closure methods 00400 // permissive: hierarchical selection, meaning that if a folder/model is selected then 00401 // its children/grandchildren need not to be selected (need not be in m_selFCO/Folder) 00402 // this is used by regular clipboard methods 00403 // 00404 inline bool CMgaDumper::CheckInClosure(CComObjPtr<IMgaAttribute> ) { return true;} 00405 inline bool CMgaDumper::CheckInClosure(CComObjPtr<IMgaConnPoint> ) { return true;} 00406 00407 bool CMgaDumper::CheckInClosure(CComObjPtr<IMgaFolder> folder) 00408 { 00409 if ( m_selFolders.empty() && m_selFcos.empty()) { 00410 // if the selected FCOs and selected Folders values are empty 00411 // then everything is in the closure 00412 return true; 00413 } 00414 00415 bool in_closure = false; 00416 00417 if (m_strictDump) 00418 { 00419 in_closure = std::find_if( m_selFolders.begin(), m_selFolders.end(), GmeEqual( folder)) != m_selFolders.end(); 00420 } 00421 else 00422 { 00423 CComObjPtr<IMgaFolder> curr_folder = folder; 00424 while ( curr_folder != NULL && !in_closure) 00425 { 00426 in_closure = std::find_if( m_selFolders.begin(), m_selFolders.end(), GmeEqual( curr_folder)) != m_selFolders.end(); 00427 00428 CComObjPtr<IMgaFolder> parent; 00429 COMTHROW(curr_folder->get_ParentFolder(PutOut( parent))); 00430 00431 curr_folder = NULL; 00432 00433 if (parent != NULL) { 00434 curr_folder = parent; 00435 } 00436 } 00437 } 00438 return in_closure; 00439 } 00440 00441 bool CMgaDumper::CheckInClosure(CComObjPtr<IMgaFCO> fco) 00442 { 00443 if ( m_selFolders.empty() && m_selFcos.empty()) { 00444 // if the selected FCOs and selected Folders values are empty 00445 // then everything is in the closure 00446 return true; 00447 } 00448 00449 bool in_closure = false; 00450 00451 if (m_strictDump) 00452 { 00453 in_closure = std::find_if( m_selFcos.begin(), m_selFcos.end(), GmeEqual( fco)) != m_selFcos.end(); 00454 } 00455 else 00456 { 00457 00458 CComObjPtr<IMgaFCO> curr_fco = fco; 00459 CComObjPtr<IMgaFCO> last_fco = fco; 00460 while ( curr_fco != NULL && !in_closure) { 00461 00462 in_closure = std::find_if( m_selFcos.begin(), m_selFcos.end(), GmeEqual( curr_fco)) != m_selFcos.end(); 00463 00464 CComObjPtr<IMgaModel> parent; 00465 COMTHROW(curr_fco->get_ParentModel(PutOut(parent))); 00466 last_fco = curr_fco; 00467 curr_fco = NULL; 00468 if (parent != NULL) { 00469 COMTHROW( ::QueryInterface(parent, curr_fco) ); 00470 } 00471 } 00472 00473 if ( !in_closure) // no parent yet (model) in closure, need to check folders 00474 { 00475 CComObjPtr<IMgaFolder> par_folder; 00476 COMTHROW( last_fco->get_ParentFolder(PutOut( par_folder))); 00477 00478 while ( par_folder != NULL && !in_closure) 00479 { 00480 in_closure = std::find_if( m_selFolders.begin(), m_selFolders.end(), GmeEqual( par_folder)) != m_selFolders.end(); 00481 00482 CComObjPtr<IMgaFolder> parent; 00483 COMTHROW(par_folder->get_ParentFolder(PutOut( parent))); 00484 00485 par_folder = NULL; 00486 00487 if (parent != NULL) 00488 par_folder = parent; 00489 } 00490 } 00491 } 00492 00493 return in_closure; 00494 } 00495 00496 // ------- Dumpers 00497 00498 void CMgaDumper::Dump(IMgaProject *project) 00499 { 00500 ASSERT( project != NULL ); 00501 00502 CComVariant variant; 00503 CComBstrObj bstr; 00504 GUID guid; 00505 00506 StartElem(_T("project")); 00507 00508 COMTHROW( project->get_GUID(PutOut(variant)) ); 00509 CopyTo(variant, guid); 00510 CopyTo(guid, PutOut(bstr)); 00511 Attr(_T("guid"), bstr); 00512 00513 Attr(_T("cdate"), project, &IMgaProject::get_CreateTime); 00514 Attr(_T("mdate"), project, &IMgaProject::get_ChangeTime); 00515 Attr(_T("version"), project, &IMgaProject::get_Version); 00516 00517 CComObjPtr<IMgaMetaProject> metaproject; 00518 COMTHROW( project->get_RootMeta(PutOut(metaproject)) ); 00519 ASSERT( metaproject != NULL ); 00520 00521 variant.Clear(); 00522 bstr.Empty(); 00523 COMTHROW( metaproject->get_GUID(PutOut(variant)) ); 00524 CopyTo(variant, guid); 00525 CopyTo(guid, PutOut(bstr)); 00526 Attr(_T("metaguid"), bstr); 00527 Attr(_T("metaversion"), metaproject, &IMgaMetaProject::get_Version); 00528 Attr(_T("metaname"), metaproject, &IMgaMetaProject::get_Name); 00529 00530 00531 00532 StartElem(_T("name")); 00533 Data(project, &IMgaProject::get_Name); 00534 EndElem(); 00535 00536 StartElem(_T("comment")); 00537 Data(project, &IMgaProject::get_Comment); 00538 EndElem(); 00539 00540 StartElem(_T("author")); 00541 Data(project, &IMgaProject::get_Author); 00542 EndElem(); 00543 00544 CComObjPtr<IMgaFolder> folder; 00545 COMTHROW( project->get_RootFolder(PutOut(folder)) ); 00546 Dump(folder); 00547 00548 EndElem(); 00549 } 00550 00551 void CMgaDumper::Dump(IMgaFolder *folder) 00552 { 00553 ASSERT( folder != NULL ); 00554 00555 StartElem(_T("folder")); 00556 00557 Attr(_T("id"), folder, &IMgaFolder::get_ID); 00558 00559 if( m_closureDump && m_v2) 00560 { 00561 // dump closureguid attribute 00562 CComObjPtr<IMgaRegNode> regnode; 00563 COMTHROW( folder->get_RegistryNode( CComBSTR( GLOBAL_ID_STR), PutOut( regnode))); 00564 long status; 00565 COMTHROW( regnode->get_Status( &status)); 00566 if( status == ATTSTATUS_HERE) 00567 { 00568 CComBstrObj guid_str; 00569 COMTHROW( regnode->get_Value( PutOut(guid_str))); 00570 if( guid_str.Length() == GLOBAL_ID_LEN) // using { 8-4-4-4-12} form 00571 Attr( _T("closureguid"), guid_str); 00572 } 00573 00574 00575 Attr( _T("closurename"), folder, &IMgaFolder::get_Name); 00576 00577 } 00578 00579 if(dumpversion >= 1) { 00580 if( m_dumpRelids) 00581 { 00582 LAttr(_T("relid"), folder, &IMgaFolder::get_RelID); 00583 LAttr(_T("childrelidcntr"), folder, &IMgaFolder::get_ChildRelIDCounter); 00584 } 00585 00586 CComBstrObj libname; 00587 COMTHROW( folder->get_LibraryName(PutOut(libname)) ); 00588 if(libname) Attr(_T("libref"),libname); 00589 00590 VARIANT_BOOL readonly; 00591 COMTHROW( folder->HasReadOnlyAccess( &readonly)); 00592 if( readonly) Attr( _T("perm"), _T("1")); 00593 } 00594 00595 CComObjPtr<IMgaMetaFolder> metafolder; 00596 COMTHROW( folder->get_MetaFolder(PutOut(metafolder)) ); 00597 Attr(_T("kind"), metafolder, &IMgaMetaFolder::get_Name); 00598 00599 if( m_dumpGuids) // this is true if Project is dumped and mgaversion of project is 2 00600 { 00601 try 00602 { 00603 CComBstrObj bs; 00604 HRESULT hr = folder->GetGuidDisp( PutOut( bs)); 00605 if( SUCCEEDED( hr) && bs && bs.Length() == 38) // {%08lX-%04X-%04x-%02X%02X-%02X%02X%02X%02X%02X%02X} <-- dumping that form (38 chars long including braces) 00606 Attr( _T("guid"), bs);//Attr( _T("guid"), IMgaObject::GetGuidDisp); 00607 00608 } catch( hresult_exception& ) 00609 { 00610 } 00611 } 00612 00613 StartElem(_T("name")); 00614 Data(folder, &IMgaFolder::get_Name); 00615 EndElem(); 00616 00617 DumpConstraints(folder); 00618 00619 Dump(folder, &IMgaFolder::get_ChildFolders); 00620 00621 // dumping the regnodes 00622 CComObjPtrVector<IMgaRegNode> v; 00623 COMTHROW( folder->get_Registry(VARIANT_FALSE, PutOut(v)) ); 00624 CComObjPtrVector<IMgaRegNode>::iterator i = v.begin(); 00625 CComObjPtrVector<IMgaRegNode>::iterator e = v.end(); 00626 00627 Sort(&v); 00628 00629 while( i != e ) 00630 { 00631 Dump(*i); 00632 00633 ++i; 00634 } 00635 00636 Dump(folder, &IMgaFolder::get_ChildFCOs); 00637 00638 EndElem(); 00639 } 00640 00641 void CMgaDumper::Dump(IMgaRegNode *regnode) 00642 { 00643 ASSERT( regnode != NULL ); 00644 00645 StartElem(_T("regnode")); 00646 00647 Attr(_T("name"), regnode, &IMgaRegNode::get_Name); 00648 00649 VARIANT_BOOL b; 00650 COMTHROW( regnode->get_Opacity(&b) ); 00651 00652 if( b != VARIANT_FALSE ) 00653 Attr(_T("isopaque"), _T("yes")); 00654 00655 long status; 00656 COMTHROW( regnode->get_Status( &status ) ); 00657 if( status == -2) // ATTSTATUS_UNDEFINED 00658 Attr(_T("status"), _T("undefined")); 00659 00660 StartElem(_T("value")); 00661 Data(regnode, &IMgaRegNode::get_Value); 00662 EndElem(); 00663 00664 // FIXME: MetaGME uses many regnodes on rootfolder, which makes progress bar freeze 00665 00666 // dumping the subnodes 00667 CComObjPtrVector<IMgaRegNode> v; 00668 COMTHROW( regnode->get_SubNodes(VARIANT_FALSE, PutOut(v)) ); 00669 Sort(&v); 00670 00671 CComObjPtrVector<IMgaRegNode>::iterator i = v.begin(); 00672 CComObjPtrVector<IMgaRegNode>::iterator e = v.end(); 00673 while( i != e ) 00674 { 00675 Dump(*i); 00676 00677 ++i; 00678 } 00679 00680 EndElem(); 00681 } 00682 00683 void CMgaDumper::Dump(IMgaObject *obj) 00684 { 00685 ASSERT( obj != NULL ); 00686 00687 objtype_enum objtype; 00688 COMTHROW( obj->get_ObjType(&objtype) ); 00689 00690 switch(objtype) 00691 { 00692 case OBJTYPE_MODEL: 00693 { 00694 CComObjPtr<IMgaModel> p; 00695 COMTHROW( ::QueryInterface(obj, p) ); 00696 Dump(p); 00697 break; 00698 } 00699 00700 case OBJTYPE_ATOM: 00701 { 00702 CComObjPtr<IMgaAtom> p; 00703 COMTHROW( ::QueryInterface(obj, p) ); 00704 Dump(p); 00705 break; 00706 } 00707 00708 case OBJTYPE_REFERENCE: 00709 { 00710 CComObjPtr<IMgaReference> p; 00711 COMTHROW( ::QueryInterface(obj, p) ); 00712 Dump(p); 00713 break; 00714 } 00715 00716 case OBJTYPE_CONNECTION: 00717 { 00718 CComObjPtr<IMgaConnection> p; 00719 COMTHROW( ::QueryInterface(obj, p) ); 00720 Dump(p); 00721 break; 00722 } 00723 00724 case OBJTYPE_SET: 00725 { 00726 CComObjPtr<IMgaSet> p; 00727 COMTHROW( ::QueryInterface(obj, p) ); 00728 Dump(p); 00729 break; 00730 } 00731 00732 case OBJTYPE_FOLDER: 00733 { 00734 CComObjPtr<IMgaFolder> p; 00735 COMTHROW( ::QueryInterface(obj, p) ); 00736 Dump(p); 00737 break; 00738 } 00739 00740 default: 00741 HR_THROW(E_INVALID_MGA); 00742 }; 00743 } 00744 00745 void CMgaDumper::DumpFCO(IMgaFCO *fco, bool dump_attrs, bool dump_name, bool dump_elems) 00746 { 00747 ASSERT( fco != NULL ); 00748 00749 if (fco_count++ % FLUSH_LIMIT == 0) 00750 { 00751 ASSERT( territory != NULL ); 00752 00753 if (fco_count >= FLUSH_LIMIT) 00754 { 00755 COMTHROW( territory->Flush() ); 00756 COMTHROW( project->CommitTransaction() ); 00757 COMTHROW( project->BeginTransaction(territory, TRANSACTION_READ_ONLY) ); 00758 } 00759 00760 if (m_progress) 00761 { 00762 static TCHAR progress_msg[512]; 00763 _stprintf_s(progress_msg, _T("Number of exported FCOs: %ld"), (long)fco_count); 00764 COMTHROW(m_progress->SetLine(0, PutInBstr(progress_msg))); 00765 COMTHROW(m_progress->SetProgress(fco_count, 0)); 00766 } 00767 } 00768 00769 if( dump_attrs ) 00770 { 00771 Attr(_T("id"), fco, &IMgaFCO::get_ID); 00772 00773 CComObjPtr<IMgaMetaFCO> metafco; 00774 COMTHROW( fco->get_Meta(PutOut(metafco)) ); 00775 Attr(_T("kind"), metafco, &IMgaMetaFCO::get_Name); 00776 00777 CComObjPtr<IMgaMetaRole> role; 00778 COMTHROW( fco->get_MetaRole(PutOut(role)) ); 00779 if( role != NULL ) 00780 Attr(_T("role"), role, &IMgaMetaRole::get_Name); 00781 00782 if( m_dumpGuids) // this is true if Project is dumped and mgaversion of project is 2 00783 { 00784 try 00785 { 00786 CComBstrObj bs; 00787 HRESULT hr = fco->GetGuidDisp( PutOut( bs)); 00788 if( SUCCEEDED( hr) && bs && bs.Length() == 38) // {%08lX-%04X-%04x-%02X%02X-%02X%02X%02X%02X%02X%02X} <-- dumping that form (38 chars long including braces) 00789 Attr( _T("guid"), bs);//Attr( _T("guid"), IMgaFCO::GetGuidDisp); 00790 00791 } catch( hresult_exception& ) 00792 { 00793 } 00794 } 00795 00796 if( m_closureDump && m_v2) 00797 { 00798 // dump closureguid attribute 00799 CComBstrObj guid_str; // this form will not create the node if is not present 00800 COMTHROW( fco->get_RegistryValue( CComBSTR( GLOBAL_ID_STR), PutOut( guid_str))); 00801 if( guid_str != 0 && guid_str.Length() == GLOBAL_ID_LEN) // using { 8-4-4-4-12} form 00802 Attr( _T("closureguid"), guid_str); 00803 00804 Attr( _T("closurename"), fco, &IMgaFCO::get_Name); 00805 00806 } 00807 00808 VARIANT_BOOL prim = VARIANT_TRUE; 00809 bool lost_basetype = false; 00810 CComObjPtr<IMgaFCO> derivedfrom; 00811 COMTHROW( fco->get_DerivedFrom(PutOut(derivedfrom)) ); 00812 if(derivedfrom != NULL ) 00813 { 00814 if (CheckInClosure(derivedfrom)) { 00815 Attr(_T("derivedfrom"), derivedfrom, &IMgaFCO::get_ID); 00816 00817 VARIANT_BOOL b; 00818 00819 COMTHROW( fco->get_IsInstance(&b) ); 00820 Attr(_T("isinstance"), b != VARIANT_FALSE ? _T("yes") : _T("no")); 00821 00822 COMTHROW( fco->get_IsPrimaryDerived(&prim) ); 00823 Attr(_T("isprimary"), prim != VARIANT_FALSE ? _T("yes") : _T("no")); 00824 } 00825 else { 00826 lost_basetype = true; 00827 } 00828 00829 if( m_closureDump && !CheckInClosure(derivedfrom)) 00830 { 00831 if ( m_dumpLibraryStubs && !CheckInClosure(derivedfrom) && !isInLibrary( fco) && isInLibrary( derivedfrom)) { //derived from a type defined in a library 00832 CComBSTR name; 00833 COMTHROW( derivedfrom->get_AbsPath( &name)); 00834 std::tstring nm; 00835 CopyTo( name, nm); 00836 00837 Attr(_T("closurelibderivedfrom"), nm); 00838 00839 VARIANT_BOOL b; 00840 00841 COMTHROW( fco->get_IsInstance(&b) ); 00842 Attr(_T("isinstance"), b != VARIANT_FALSE ? _T("yes") : _T("no")); 00843 00844 COMTHROW( fco->get_IsPrimaryDerived(&prim) ); 00845 Attr(_T("isprimary"), prim != VARIANT_FALSE ? _T("yes") : _T("no")); 00846 } 00847 else if( m_v2) 00848 { 00849 CComBSTR name; 00850 00851 COMTHROW( derivedfrom->get_AbsPath( &name)); 00852 std::tstring nm; 00853 CopyTo( name, nm); 00854 00855 COMTHROW( fco->get_AbsPath( &name)); 00856 std::tstring nm2; 00857 CopyTo( name, nm2); 00858 00859 Attr(_T("closure2derivedfrom"), makeRel( nm, nm2)); 00860 00861 VARIANT_BOOL b; 00862 00863 COMTHROW( fco->get_IsInstance(&b) ); 00864 Attr(_T("isinstance"), b != VARIANT_FALSE ? _T("yes") : _T("no")); 00865 00866 COMTHROW( fco->get_IsPrimaryDerived(&prim) ); 00867 Attr(_T("isprimary"), prim != VARIANT_FALSE ? _T("yes") : _T("no")); 00868 } 00869 } 00870 00871 if( m_closureDump && m_v2) 00872 { 00873 CComBstrObj guid; 00874 COMTHROW( derivedfrom->get_RegistryValue( CComBSTR( GLOBAL_ID_STR), PutOut( guid))); 00875 if( guid != 0 && guid.Length() == GLOBAL_ID_LEN) 00876 Attr( _T("smartDerivedFromGUID"), guid); 00877 } 00878 } 00879 if(prim && (dumpversion >= 1) && (!lost_basetype) && m_dumpRelids) 00880 LAttr(_T("relid"), fco, &IMgaFCO::get_RelID); 00881 00882 VARIANT_BOOL readonly; 00883 COMTHROW( fco->HasReadOnlyAccess( &readonly)); 00884 if( readonly) Attr( _T("perm"), _T("1")); 00885 } 00886 00887 if( dump_name ) 00888 { 00889 StartElem(_T("name")); 00890 Data(fco, &IMgaFCO::get_Name); 00891 EndElem(); 00892 } 00893 00894 if( dump_elems ) 00895 { 00896 DumpConstraints(fco); 00897 00898 // dumping the regnodes 00899 CComObjPtrVector<IMgaRegNode> v; 00900 COMTHROW( fco->get_Registry(VARIANT_FALSE, PutOut(v)) ); 00901 CComObjPtrVector<IMgaRegNode>::iterator i = v.begin(); 00902 CComObjPtrVector<IMgaRegNode>::iterator e = v.end(); 00903 00904 Sort(&v); 00905 00906 while( i != e ) 00907 { 00908 Dump(*i); 00909 00910 ++i; 00911 } 00912 00913 Dump(fco, &IMgaFCO::get_Attributes); 00914 } 00915 } 00916 00917 void CMgaDumper::Dump(IMgaModel *model) 00918 { 00919 ASSERT( model != NULL ); 00920 00921 StartElem(_T("model")); 00922 00923 DumpFCO(model, true, false, false); 00924 if(dumpversion >= 1 && m_dumpRelids) LAttr(_T("childrelidcntr"), model, &IMgaModel::get_ChildRelIDCounter); 00925 DumpFCO(model, false, true, true); 00926 00927 Dump(model, &IMgaModel::get_ChildFCOs); 00928 00929 EndElem(); 00930 } 00931 00932 void CMgaDumper::DumpConstraints(IMgaObject *object) 00933 { 00934 ASSERT( object != NULL ); 00935 00936 CComObjPtrVector<IMgaConstraint> v; 00937 00938 CComObjPtr<IMgaFCO> fco; 00939 if( SUCCEEDED(::QueryInterface(object, fco)) ) 00940 { 00941 COMTHROW( fco->get_Constraints(VARIANT_FALSE, PutOut(v)) ); 00942 } 00943 else 00944 { 00945 CComObjPtr<IMgaFolder> folder; 00946 COMTHROW( ::QueryInterface(object, folder) ); 00947 COMTHROW( folder->get_Constraints(VARIANT_FALSE, PutOut(v)) ); 00948 } 00949 00950 CComObjPtrVector<IMgaConstraint>::iterator i = v.begin(); 00951 CComObjPtrVector<IMgaConstraint>::iterator e = v.end(); 00952 while( i != e ) 00953 { 00954 Dump(*i); 00955 00956 ++i; 00957 } 00958 } 00959 00960 void CMgaDumper::Dump(IMgaConstraint *constraint) 00961 { 00962 ASSERT( constraint != NULL ); 00963 00964 StartElem(_T("constraint")); 00965 00966 StartElem(_T("name")); 00967 Data(constraint, &IMgaConstraint::get_Name); 00968 EndElem(); 00969 00970 StartElem(_T("value")); 00971 Data(constraint, &IMgaConstraint::get_Expression); 00972 EndElem(); 00973 00974 EndElem(); 00975 } 00976 00977 void CMgaDumper::Dump(IMgaAttribute *attribute) 00978 { 00979 ASSERT( attribute != NULL ); 00980 00981 StartElem(_T("attribute")); 00982 00983 CComObjPtr<IMgaMetaAttribute> metaattr; 00984 COMTHROW( attribute->get_Meta(PutOut(metaattr)) ); 00985 Attr(_T("kind"), metaattr, &IMgaMetaAttribute::get_Name); 00986 00987 long status; 00988 COMTHROW( attribute->get_Status(&status) ); 00989 if( status < 0 ) 00990 Attr(_T("status"), _T("meta")); 00991 else if( status > 0 ) 00992 Attr(_T("status"), _T("inherited")); 00993 00994 StartElem(_T("value")); 00995 00996 attval_enum attval; 00997 COMTHROW( metaattr->get_ValueType(&attval) ); 00998 00999 std::tstring data; 01000 01001 switch(attval) 01002 { 01003 case ATTVAL_STRING: 01004 case ATTVAL_ENUM: 01005 case ATTVAL_DYNAMIC: 01006 { 01007 CComBstrObj bstr; 01008 COMTHROW( attribute->get_StringValue(PutOut(bstr)) ); 01009 CopyTo(bstr, data); 01010 break; 01011 } 01012 01013 case ATTVAL_INTEGER: 01014 { 01015 long l; 01016 COMTHROW( attribute->get_IntValue(&l) ); 01017 Format(data, _T("%ld"), l); 01018 break; 01019 } 01020 01021 case ATTVAL_DOUBLE: 01022 { 01023 double d; 01024 COMTHROW( attribute->get_FloatValue(&d) ); 01025 wchar_t dblbuf[40]; 01026 _swprintf_s_l(dblbuf, sizeof(dblbuf) / sizeof(dblbuf[0]), L"%.17g", c_locale, d); 01027 data = dblbuf; 01028 break; 01029 } 01030 01031 case ATTVAL_BOOLEAN: 01032 { 01033 VARIANT_BOOL b; 01034 COMTHROW( attribute->get_BoolValue(&b) ); 01035 01036 if( b != VARIANT_FALSE ) 01037 data = _T("true"); 01038 else 01039 data = _T("false"); 01040 01041 break; 01042 } 01043 01044 case ATTVAL_REFERENCE: 01045 { 01046 CComObjPtr<IMgaFCO> fco; 01047 COMTHROW( attribute->get_FCOValue(PutOut(fco)) ); 01048 01049 if( (fco != NULL) && (CheckInClosure(fco)) ) 01050 { 01051 CComBstrObj bstr; 01052 COMTHROW( fco->get_ID(PutOut(bstr)) ); 01053 CopyTo(bstr, data); 01054 } 01055 break; 01056 } 01057 01058 default: 01059 HR_THROW(E_INVALID_META); 01060 }; 01061 01062 Data(data); 01063 EndElem(); 01064 01065 // Dump(attribute, IMgaAttribute::get_Registry); 01066 01067 EndElem(); 01068 } 01069 01070 void CMgaDumper::Dump(IMgaAtom *atom) 01071 { 01072 ASSERT( atom != NULL ); 01073 01074 StartElem(_T("atom")); 01075 01076 DumpFCO(atom); 01077 01078 EndElem(); 01079 } 01080 01081 void CMgaDumper::Dump(IMgaReference *reference) 01082 { 01083 ASSERT( reference != NULL ); 01084 01085 StartElem(_T("reference")); 01086 01087 DumpFCO(reference, true, false, false); 01088 01089 CComObjPtr<IMgaFCO> fco; 01090 COMTHROW( reference->get_Referred(PutOut(fco)) ); 01091 01092 if( fco != NULL) 01093 { 01094 if( CheckInClosure( fco)) // regular dump or the fco is really in the closure 01095 Attr(_T("referred"), fco, &IMgaFCO::get_ID); 01096 01097 if( m_closureDump) 01098 { 01099 if ( m_dumpLibraryStubs && !CheckInClosure( fco) && !isInLibrary( reference) && isInLibrary( fco)) //reference pointing out to a library 01100 { 01101 CComBSTR name; 01102 COMTHROW( fco->get_AbsPath( &name)); 01103 std::tstring nm; 01104 CopyTo( name, nm); 01105 01106 Attr(_T("closurelibreferred"), nm); 01107 } 01108 01109 // dump the relativepath of the referred object if v2 01110 else if( m_v2) // _T("else") introd freshly, not to dump to paths, the parser will check first for closurelibreferred 01111 { 01112 CComBSTR name; 01113 COMTHROW( fco->get_AbsPath( &name)); 01114 std::tstring nm; 01115 CopyTo( name, nm); 01116 01117 COMTHROW( reference->get_AbsPath( &name)); 01118 std::tstring nm2; 01119 CopyTo( name, nm2); 01120 01121 01122 Attr(_T("closure2referred"), makeRel( nm, nm2)); 01123 } 01124 01125 // dump guid of fco if m_v2 01126 if( m_v2) 01127 { 01128 CComBstrObj ref_guid; 01129 COMTHROW( fco->get_RegistryValue( CComBSTR( GLOBAL_ID_STR), PutOut( ref_guid))); 01130 if( ref_guid != 0 && ref_guid.Length() == GLOBAL_ID_LEN) // valid guid 01131 Attr( _T("smartReferredGUID"), ref_guid); 01132 } 01133 } 01134 } 01135 01136 01137 CComObjPtr<IMgaFCO> base; 01138 COMTHROW( reference->get_DerivedFrom(PutOut(base))); 01139 if(base && CheckInClosure(base) 01140 || base && m_closureDump && m_v2) { 01141 short stat; 01142 COMTHROW( reference->CompareToBase(&stat)); 01143 if(!stat) { 01144 Attr(_T("isbound"), _T("yes") ); 01145 } 01146 } 01147 01148 DumpFCO(reference, false, true, true); 01149 01150 EndElem(); 01151 } 01152 01153 void CMgaDumper::Dump(IMgaConnection *connection) 01154 { 01155 ASSERT( connection != NULL ); 01156 01157 StartElem(_T("connection")); 01158 01159 bool skipdump = false; 01160 01161 CComObjPtr<IMgaFCO> base; 01162 COMTHROW( connection->get_DerivedFrom(PutOut(base))); 01163 if(base && CheckInClosure(base) 01164 || base && m_closureDump && m_v2) { 01165 short stat; 01166 COMTHROW( connection->CompareToBase(NULL, &stat)); 01167 if(!stat) { 01168 Attr(_T("isbound"), _T("yes") ); 01169 skipdump = true; 01170 } 01171 } 01172 01173 if( m_closureDump && m_v2) 01174 DumpConnDetails( CComObjPtr<IMgaConnection>( connection)); 01175 01176 DumpFCO(connection); 01177 01178 if(!skipdump) 01179 Dump(connection, &IMgaConnection::get_ConnPoints); 01180 01181 EndElem(); 01182 } 01183 01184 void CMgaDumper::Dump(IMgaSet *set) 01185 { 01186 ASSERT( set != NULL ); 01187 01188 StartElem(_T("set")); 01189 01190 DumpFCO(set, true, false, false); 01191 bool skipdump = false; 01192 CComObjPtr<IMgaFCO> base; 01193 COMTHROW( set->get_DerivedFrom(PutOut(base))); 01194 if(base && CheckInClosure(base) 01195 || base && m_closureDump && m_v2) { 01196 short stat; 01197 COMTHROW( set->CompareToBase(&stat)); 01198 if(!stat) { 01199 Attr(_T("isbound"), _T("yes") ); 01200 skipdump = true; 01201 } 01202 } 01203 01204 01205 if(!skipdump) { 01206 CComObjPtrVector<IMgaFCO> members; 01207 COMTHROW( set->get_Members(PutOut(members)) ); 01208 Sort( &members); // we sort the set members by ID 01209 01210 if( m_closureDump) 01211 { 01212 CComBSTR name; 01213 COMTHROW( set->get_AbsPath( &name)); 01214 CopyTo( name, m_currAbsPath); // will be used by the DumpIDRefs 01215 01216 if( m_v2) 01217 { 01218 std::tstring memberguids = DumpMixedGUIDRefs( members); // uses m_currAbsPath 01219 if( !memberguids.empty()) Attr( _T("smartMemberGUIDs"), memberguids); 01220 } 01221 } 01222 01223 DumpIDRefs(_T("members"), members); // might use m_currAbsPath 01224 } 01225 01226 DumpFCO(set, false, true, true); 01227 01228 EndElem(); 01229 } 01230 01231 void CMgaDumper::Dump(IMgaConnPoint *connpoint) 01232 { 01233 ASSERT( connpoint != NULL ); 01234 01235 StartElem(_T("connpoint")); 01236 01237 #ifdef _DEBUG 01238 CComBSTR rolename; 01239 connpoint->get_ConnRole(&rolename); 01240 ASSERT(rolename.Length() != 0); 01241 #endif 01242 01243 Attr(_T("role"), connpoint, &IMgaConnPoint::get_ConnRole); 01244 01245 CComObjPtr<IMgaFCO> target; 01246 COMTHROW( connpoint->get_Target(PutOut(target)) ); 01247 01248 if( target == NULL ) 01249 HR_THROW(E_INVALID_MGA); 01250 01251 01252 CComPtr<IMgaConnection> conn; 01253 COMTHROW( connpoint->get_Owner(&conn)); 01254 01255 CComObjPtr<IMgaFCO> base; 01256 COMTHROW( conn->get_DerivedFrom(PutOut(base))); 01257 if(base && CheckInClosure(base) 01258 || base && m_closureDump && m_v2) { 01259 short stat; 01260 COMTHROW( conn->CompareToBase(connpoint, &stat)); 01261 if(!stat) { 01262 Attr(_T("isbound"), _T("yes") ); 01263 } 01264 } 01265 01266 Attr(_T("target"), target, &IMgaFCO::get_ID); 01267 01268 if( m_closureDump) 01269 { 01270 CComBSTR name; 01271 COMTHROW( conn->get_AbsPath( &name)); 01272 CopyTo( name, m_currAbsPath); // used by DumpIDRefs 01273 01274 // m_dumpLibraryStubs is true, so the connection to a library element will be dumped with "closurelibtarget" attribute and a dummy! "target" attribute 01275 if ( m_dumpLibraryStubs && !isInLibrary( conn) && isInLibrary( target)) 01276 { 01277 CComBSTR name; 01278 COMTHROW( target->get_AbsPath( &name)); 01279 std::tstring nm; 01280 CopyTo( name, nm); 01281 01282 Attr(_T("closurelibtarget"), nm); 01283 } 01284 else if( m_v2) // closure v2 01285 { 01286 CComBSTR name; 01287 COMTHROW( target->get_AbsPath( &name)); 01288 std::tstring nm; 01289 CopyTo( name, nm); 01290 01291 Attr(_T("closure2target"), makeRel( nm, m_currAbsPath)); 01292 } 01293 } 01294 01295 01296 CComObjPtrVector<IMgaFCO> refs; 01297 COMTHROW( connpoint->get_References(PutOut(refs)) ); 01298 // m_currAbsPath is set above, at the "closure2target" dump 01299 DumpIDRefs(_T("refs"), refs); 01300 01301 EndElem(); 01302 } 01303 01304 void CMgaDumper::DumpIDRefs(const TCHAR *name, CComObjPtrVector<IMgaFCO> &fcos) 01305 { 01306 if( !fcos.empty() ) 01307 { 01308 std::tstring idrefs, clos_idrefs; 01309 01310 CComObjPtrVector<IMgaFCO>::iterator i = fcos.begin(); 01311 CComObjPtrVector<IMgaFCO>::iterator e = fcos.end(); 01312 while( i != e ) 01313 { 01314 if( m_closureDump) 01315 { 01316 CComBSTR name; 01317 COMTHROW( (*i)->get_AbsPath( &name)); 01318 std::tstring nm; 01319 CopyTo( name, nm); 01320 01321 if( !clos_idrefs.empty() ) 01322 clos_idrefs += ' '; 01323 01324 clos_idrefs += makeRel( nm, m_currAbsPath); 01325 } 01326 01327 if (!CheckInClosure(*i)) { 01328 ++i; // inserted by ZolMol 01329 continue; 01330 } 01331 CComBstrObj bstr; 01332 COMTHROW( (*i)->get_ID(PutOut(bstr)) ); 01333 01334 std::tstring id; 01335 CopyTo(bstr, id); 01336 01337 if( !idrefs.empty() ) 01338 idrefs += ' '; 01339 01340 idrefs += id; 01341 01342 ++i; 01343 } 01344 01345 if ( !idrefs.empty()) 01346 Attr(name, idrefs); 01347 01348 if( m_closureDump && m_v2 && !clos_idrefs.empty()) // closure v2 01349 { 01350 std::tstring clos_name(_T("closure2")); clos_name += name; 01351 Attr( clos_name.c_str(), clos_idrefs); 01352 } 01353 } 01354 } 01355 std::tstring CMgaDumper::DumpGUIDRefs( CComObjPtrVector<IMgaFCO>& fcos) 01356 { 01357 std::tstring guidrefs; 01358 01359 for( CComObjPtrVector<IMgaFCO>::iterator i = fcos.begin(); i != fcos.end(); ++i) 01360 { 01361 CComBSTR bstr; 01362 COMTHROW( (*i)->get_RegistryValue( CComBSTR( GLOBAL_ID_STR), &bstr)); 01363 01364 if( bstr != 0 && bstr.Length() == GLOBAL_ID_LEN) 01365 { 01366 std::tstring guid; 01367 CopyTo(bstr, guid); 01368 01369 if( !guidrefs.empty() ) 01370 guidrefs += ' '; 01371 01372 guidrefs += guid; 01373 } 01374 else 01375 return _T(""); // if one guid not found, then all are disregarded 01376 } 01377 01378 return guidrefs; 01379 } 01380 01381 std::tstring CMgaDumper::DumpMixedGUIDRefs( CComObjPtrVector<IMgaFCO>& fcos) 01382 { 01383 // this method produces a sequence of the {guid}=path forms 01384 //{E200BEEB-34BC-4271-A134-AA5728C38124}\\/@../@module_ref1|kind=module_ref|relpos=0 01385 std::tstring guidrefs; 01386 01387 for( CComObjPtrVector<IMgaFCO>::iterator i = fcos.begin(); i != fcos.end(); ++i) 01388 { 01389 01390 CComBSTR name; 01391 COMTHROW( (*i)->get_AbsPath( &name)); 01392 std::tstring nm; 01393 CopyTo( name, nm); 01394 01395 if( !guidrefs.empty() ) 01396 guidrefs += ' '; 01397 01398 CComBSTR bstr; 01399 COMTHROW( (*i)->get_RegistryValue( CComBSTR( GLOBAL_ID_STR), &bstr)); 01400 01401 if( bstr != 0 && bstr.Length() == GLOBAL_ID_LEN) 01402 { 01403 std::tstring guid; 01404 CopyTo(bstr, guid); 01405 01406 01407 guidrefs += guid; 01408 guidrefs += '\\'; 01409 } 01410 //else 01411 // return ""; // if one guid not found, then all are disregarded 01412 01413 guidrefs += makeRel( nm, m_currAbsPath); 01414 } 01415 01416 return guidrefs; 01417 } 01418 01419 //sort the RegNode Vector in place by Name 01420 void CMgaDumper::Sort(CComObjPtrVector<IMgaRegNode> *v) 01421 { 01422 int n = v->size(); 01423 01424 //small speed up, build a vector of strings first, then sort the strings 01425 //while doing the sort operations on the original vector, so we don't have 01426 //to call the get_Name function each time we look at a RegNode 01427 std::vector<std::tstring> vPrime; 01428 for (int i=0; i<n; i++) 01429 { 01430 CComBSTR bstr; 01431 COMTHROW((*v)[i]->get_Name(&bstr)); 01432 std::tstring s; 01433 CopyTo(bstr,s); 01434 vPrime.push_back(s); 01435 } 01436 01437 //in place insertion sort 01438 for (int x=1; x<n; x++) 01439 { 01440 std::tstring index = vPrime[x]; 01441 CComObjPtr<IMgaRegNode> indexRegNode = (*v)[x]; 01442 int y = x; 01443 01444 while ((y>0)&&(vPrime[y-1].compare(index)>0)) 01445 { 01446 vPrime[y]=vPrime[y-1]; 01447 01448 (*v)[y]=(*v)[y-1]; 01449 01450 --y; 01451 } 01452 01453 vPrime[y] = index; 01454 (*v)[y] = indexRegNode; 01455 } 01456 01457 } 01458 01459 //Sort the Attribute Vector by Kind 01460 void CMgaDumper::Sort(CComObjPtrVector<IMgaAttribute> *v) 01461 { 01462 int n = v->size(); 01463 01464 //small speed up, build a vector of strings first, then sort the strings 01465 //while doing the sort operations on the original vector, so we don't have 01466 //to get the Kind Name every time 01467 std::vector<std::tstring> vPrime; 01468 for (int i=0; i<n; i++) 01469 { 01470 CComBSTR bstr; 01471 CComPtr<IMgaMetaAttribute> meta; 01472 COMTHROW((*v)[i]->get_Meta(&meta)); 01473 COMTHROW(meta->get_Name(&bstr)); 01474 std::tstring s; 01475 CopyTo(bstr,s); 01476 vPrime.push_back(s); 01477 } 01478 01479 //in place insertion sort 01480 for (int x=1; x<n; x++) 01481 { 01482 std::tstring index = vPrime[x]; 01483 CComObjPtr<IMgaAttribute> indexAttr = (*v)[x]; 01484 int y = x; 01485 01486 while ((y>0)&&(vPrime[y-1].compare(index)>0)) 01487 { 01488 vPrime[y]=vPrime[y-1]; 01489 01490 (*v)[y]=(*v)[y-1]; 01491 01492 --y; 01493 } 01494 01495 vPrime[y] = index; 01496 (*v)[y] = indexAttr; 01497 } 01498 } 01499 01500 //Sort the Connection Point Vector by Target ID 01501 void CMgaDumper::Sort(CComObjPtrVector<IMgaConnPoint> *v) 01502 { 01503 int n = v->size(); 01504 01505 //small speed up, build a vector of strings first, then sort the strings 01506 //while doing the sort operations on the original vector, so we don't have 01507 //to get the Target ID every time 01508 std::vector<std::tstring> vPrime; 01509 for (int i=0; i<n; i++) 01510 { 01511 CComBSTR bstr; 01512 CComPtr<IMgaFCO> fco; 01513 COMTHROW((*v)[i]->get_Target(&fco)); 01514 COMTHROW(fco->get_ID(&bstr)); 01515 std::tstring s; 01516 CopyTo(bstr,s); 01517 // Tie-break sort on role, for self-connections 01518 CComBSTR role; 01519 COMTHROW((*v)[i]->get_ConnRole(&role)); 01520 s += role; 01521 vPrime.push_back(s); 01522 } 01523 01524 //in place insertion sort 01525 for (int x=1; x<n; x++) 01526 { 01527 std::tstring index = vPrime[x]; 01528 CComObjPtr<IMgaConnPoint> indexConnPoint = (*v)[x]; 01529 int y = x; 01530 01531 while ((y>0)&&(vPrime[y-1].compare(index)>0)) 01532 { 01533 vPrime[y]=vPrime[y-1]; 01534 01535 (*v)[y]=(*v)[y-1]; 01536 01537 --y; 01538 } 01539 01540 vPrime[y] = index; 01541 (*v)[y] = indexConnPoint; 01542 } 01543 } 01544 01545 //sort the Folder Vector by ID 01546 void CMgaDumper::Sort(CComObjPtrVector<IMgaFolder> *v) 01547 { 01548 int n = v->size(); 01549 01550 //small speed up, build a vector of strings first, then sort the strings 01551 //while doing the sort operations on the original vector, so we don't have 01552 //to call the get_ID function each time we look at a Folder 01553 std::vector<std::tstring> vPrime; 01554 for (int i=0; i<n; i++) 01555 { 01556 CComBSTR bstr; 01557 COMTHROW((*v)[i]->get_ID(&bstr)); 01558 std::tstring s; 01559 CopyTo(bstr,s); 01560 vPrime.push_back(s); 01561 } 01562 01563 //in place insertion sort 01564 for (int x=1; x<n; x++) 01565 { 01566 std::tstring index = vPrime[x]; 01567 CComObjPtr<IMgaFolder> indexFolder = (*v)[x]; 01568 int y = x; 01569 01570 while ((y>0)&&(vPrime[y-1].compare(index)>0)) 01571 { 01572 vPrime[y]=vPrime[y-1]; 01573 01574 (*v)[y]=(*v)[y-1]; 01575 01576 --y; 01577 } 01578 01579 vPrime[y] = index; 01580 (*v)[y] = indexFolder; 01581 } 01582 01583 } 01584 01585 //Sort the FCO vector in place by ID 01586 void CMgaDumper::Sort(CComObjPtrVector<IMgaFCO> *v) 01587 { 01588 int n = v->size(); 01589 01590 //small speed up, build a vector of strings first, then sort the strings 01591 //while doing the sort operations on the original vector, so we don't have 01592 //to call the get_ID function each time we look at an FCO 01593 std::vector<std::tstring> vPrime; 01594 for (int i=0; i<n; i++) 01595 { 01596 CComBSTR bstr; 01597 COMTHROW((*v)[i]->get_ID(&bstr)); 01598 std::tstring s; 01599 CopyTo(bstr,s); 01600 vPrime.push_back(s); 01601 } 01602 01603 //in place insertion sort 01604 for (int x=1; x<n; x++) 01605 { 01606 std::tstring index = vPrime[x]; 01607 CComObjPtr<IMgaFCO> indexFCO = (*v)[x]; 01608 int y = x; 01609 01610 while ((y>0)&&(vPrime[y-1].compare(index)>0)) 01611 { 01612 vPrime[y]=vPrime[y-1]; 01613 01614 (*v)[y]=(*v)[y-1]; 01615 01616 --y; 01617 } 01618 01619 vPrime[y] = index; 01620 (*v)[y] = indexFCO; 01621 } 01622 01623 } 01624 01625 void CMgaDumper::putInTerritory( CComObjPtrVector<IMgaFCO>& fco_vec) 01626 { 01627 CComObjPtrVector<IMgaFCO>::iterator i = fco_vec.begin(); 01628 for( ; i != fco_vec.end(); ++i ) 01629 { 01630 CComObjPtr<IMgaObject> obj; 01631 COMTHROW(territory->OpenObj(*i, PutOut(obj))); 01632 CComObjPtr<IMgaFCO> fco; 01633 COMTHROW(obj.QueryInterface(fco)); 01634 *i = fco; 01635 } 01636 } 01637 01638 void CMgaDumper::putInTerritory( CComObjPtrVector<IMgaFolder>& fold_vec) 01639 { 01640 CComObjPtrVector<IMgaFolder>::iterator j = fold_vec.begin(); 01641 for( ; j != fold_vec.end(); ++j ) 01642 { 01643 CComObjPtr<IMgaObject> obj; 01644 COMTHROW(territory->OpenObj(*j, PutOut(obj))); 01645 CComObjPtr<IMgaFolder> fold; 01646 COMTHROW(obj.QueryInterface(fold)); 01647 *j = fold; 01648 } 01649 } 01650 01651 // 01652 // method called from the DumpFCO 01653 // it is zombie-aware since it may happen that an object is placed to the clipboard 01654 // then deleted, then the clipboard may be dumped when the project is closed 01655 void CMgaDumper::removeInnerObjs() 01656 { 01657 bool zombies_found = false; 01658 // try to remove those objects which are part of (child, grandchild) of another selected object 01659 CComObjPtrVector<IMgaFCO>::iterator i = m_selFcos.begin(); 01660 while( i != m_selFcos.end()) 01661 { 01662 bool zombie = false; 01663 long status; 01664 COMTHROW( (*i)->get_Status(&status)); 01665 if (status != OBJECT_EXISTS) 01666 { 01667 zombies_found = zombie = true; 01668 } 01669 01670 bool found_parent = false; 01671 if( !zombie) 01672 { 01673 CComObjPtr<IMgaFCO> last_fco = *i, curr_fco = *i; 01674 do 01675 { 01676 CComObjPtr<IMgaModel> parent; 01677 COMTHROW( curr_fco->get_ParentModel(PutOut(parent))); 01678 last_fco = curr_fco; 01679 curr_fco = NULL; 01680 if (parent != NULL) { 01681 COMTHROW( ::QueryInterface(parent, curr_fco) ); 01682 found_parent = std::find_if( m_selFcos.begin(), m_selFcos.end(), GmeEqual( curr_fco)) != m_selFcos.end(); 01683 } 01684 } while ( curr_fco != NULL && !found_parent); 01685 01686 if ( !found_parent) // no parent found in the set of fcos 01687 { 01688 CComObjPtr<IMgaFolder> par_folder; 01689 COMTHROW( last_fco->get_ParentFolder(PutOut( par_folder))); 01690 01691 while ( par_folder != NULL && !found_parent) 01692 { 01693 found_parent = std::find_if( m_selFolders.begin(), m_selFolders.end(), GmeEqual( par_folder)) != m_selFolders.end(); 01694 01695 CComObjPtr<IMgaFolder> parent; 01696 COMTHROW( par_folder->get_ParentFolder(PutOut( parent))); 01697 01698 par_folder = parent; 01699 } 01700 } 01701 } 01702 01703 if ( found_parent || zombie) 01704 i = m_selFcos.erase( i); 01705 else 01706 ++i; 01707 } 01708 01709 01710 // try to remove those folders which are part of (child, grandchild) of another selected folder 01711 CComObjPtrVector<IMgaFolder>::iterator k = m_selFolders.begin(); 01712 while( k != m_selFolders.end()) 01713 { 01714 bool zombie = false; 01715 long status; 01716 COMTHROW( (*k)->get_Status(&status)); 01717 if (status != OBJECT_EXISTS) 01718 { 01719 zombies_found = zombie = true; 01720 } 01721 01722 bool found_parent = false; 01723 if( !zombie) 01724 { 01725 CComObjPtr<IMgaFolder> par_folder; 01726 COMTHROW( (*k)->get_ParentFolder(PutOut( par_folder))); 01727 01728 while ( par_folder != NULL && !found_parent) 01729 { 01730 found_parent = std::find_if( m_selFolders.begin(), m_selFolders.end(), GmeEqual( par_folder)) != m_selFolders.end(); 01731 01732 CComObjPtr<IMgaFolder> parent; 01733 COMTHROW(par_folder->get_ParentFolder(PutOut( parent))); 01734 par_folder = parent; 01735 } 01736 } 01737 01738 if ( found_parent || zombie) 01739 k = m_selFolders.erase( k); 01740 else 01741 ++k; 01742 } 01743 01744 ASSERT( zombies_found || m_selFolders.size() + m_selFcos.size() > 0); 01745 } 01746 01747 STDMETHODIMP CMgaDumper::DumpClos( IMgaFCOs *p_sel_fcos, IMgaFolders *p_sel_folds, BSTR xmlfile, int dump_options) 01748 { 01749 m_closureDump = true; 01750 m_strictDump = true; // strict dump meaning that all dumped objects must be strictly in the closure 01751 01752 m_dumpRelids = false; // dumpversion = 2; // no relids dumped 01753 m_dumpGuids = true; // dump these, as they are needed by new features 01754 01755 m_dumpLibraryStubs = (dump_options & 0x1) == 0x1; // dump library stubs ( absolute path used as libreferred or libderivedfrom attribute) 01756 m_v2 = (dump_options & 0x2) == 0x2; 01757 01758 COMTRY 01759 { 01760 if ( p_sel_fcos ) 01761 CopyTo( p_sel_fcos, m_selFcos); 01762 01763 if ( p_sel_folds) 01764 CopyTo( p_sel_folds, m_selFolders); 01765 01766 CComObjPtr<IMgaProject> project; 01767 01768 if ( !m_selFcos.empty()) 01769 COMTHROW( m_selFcos.front()->get_Project( PutOut( project)) ); 01770 else if ( !m_selFolders.empty()) 01771 COMTHROW( m_selFolders.front()->get_Project( PutOut( project)) ); 01772 else 01773 return S_OK; 01774 01775 01776 InitDump( project, xmlfile, _bstr_t(L"UTF-16")); 01777 01778 putInTerritory( m_selFcos); 01779 putInTerritory( m_selFolders); 01780 01781 if ( false) // clipboard format 01782 { 01783 ofs << L"<!DOCTYPE clipboard SYSTEM \"mgaclosure.dtd\" [\n"; 01784 ofs << L"\t<!ELEMENT clipboard (folder|model|atom|reference|set|connection|regnode)*>\n"; 01785 ofs << L"\t<!ATTLIST clipboard\n"; 01786 ofs << L"\t\tclosureversion CDATA #IMPLIED\n"; 01787 ofs << L"\t\tacceptingkind CDATA #IMPLIED\n"; 01788 ofs << L"\t\tparadigmnamehint CDATA #IMPLIED\n"; // just for compatibility with raw copied data 01789 ofs << L"\t>\n"; 01790 ofs << L"]>\n\n"; 01791 01792 StartElem(_T("clipboard")); 01793 Attr(_T("closureversion"), _T("1")); 01794 Dump( project); 01795 EndElem(); 01796 } 01797 else 01798 { 01799 ofs << L"<!DOCTYPE project SYSTEM \"mgaclosure.dtd\">\n\n"; 01800 01801 Dump( project); 01802 } 01803 DoneDump(false); 01804 } 01805 COMCATCH( DoneDump(true); ) 01806 01807 m_selFcos.clear(); 01808 m_selFolders.clear(); 01809 } 01810 01811 STDMETHODIMP CMgaDumper::DumpClosR( 01812 IMgaFCOs *p_sel_fcos, IMgaFolders *p_sel_folds, BSTR xmlfile, 01813 IMgaFCOs *p_top_fcos, IMgaFolders *p_top_folds, int dump_options, BSTR abspath, BSTR acceptingkinds) 01814 { 01815 m_closureDump = true; 01816 m_strictDump = true; // strict dump meaning that all dumped objects must be strictly in the closure 01817 m_dumpRelids = false; //dumpversion = 2; // no relids dumped 01818 m_dumpGuids = true; // dump these, as they are needed by new features 01819 01820 m_dumpLibraryStubs = (dump_options & 0x1) == 0x1; // dump library stubs ( absolute path used as closurelibreferred, closurelibderivedfrom, closurelibtarget attribute) 01821 m_v2 = (dump_options & 0x2) == 0x2; // dump the closure2members, closure2refs like attributes 01822 01823 std::tstring version_string; 01824 if( dump_options & 0x4) 01825 version_string = _T("4"); 01826 else 01827 version_string = _T("1"); 01828 01829 //CopyTo( abspath, m_currParAbsPath); 01830 01831 COMTRY 01832 { 01833 if ( p_sel_fcos ) 01834 CopyTo( p_sel_fcos, m_selFcos); 01835 01836 if ( p_sel_folds) 01837 CopyTo( p_sel_folds, m_selFolders); 01838 01839 CComObjPtr<IMgaProject> project; 01840 01841 if ( !m_selFcos.empty()) 01842 COMTHROW( m_selFcos.front()->get_Project( PutOut( project)) ); 01843 else if ( !m_selFolders.empty()) 01844 COMTHROW( m_selFolders.front()->get_Project( PutOut( project)) ); 01845 else 01846 return S_OK; 01847 01848 CComObjPtrVector<IMgaFCO> parentless_fcos; // parentless fcos from the selected set 01849 CComObjPtrVector<IMgaFolder> parentless_folders; // parentless folders from the selected set 01850 01851 if ( p_top_fcos ) 01852 CopyTo( p_top_fcos, parentless_fcos); 01853 01854 if ( p_top_folds) 01855 CopyTo( p_top_folds, parentless_folders); 01856 01857 if ( parentless_fcos.empty() && parentless_folders.empty()) 01858 { 01859 // this case should be handled by the DumpClos() 01860 ASSERT( 0); 01861 return DumpClos( p_sel_fcos, p_sel_folds, xmlfile, dump_options); 01862 } 01863 01864 InitDump( project, xmlfile, _bstr_t(L"UTF-16")); 01865 01866 putInTerritory( m_selFcos); 01867 putInTerritory( parentless_fcos); 01868 putInTerritory( m_selFolders); 01869 putInTerritory( parentless_folders); 01870 01871 ofs << L"<!DOCTYPE clipboard SYSTEM \"mgaclosure.dtd\" [\n"; 01872 ofs << L"\t<!ELEMENT clipboard (folder|model|atom|reference|set|connection|regnode)*>\n"; 01873 ofs << L"\t<!ATTLIST clipboard\n"; 01874 ofs << L"\t\tclosureversion CDATA #IMPLIED\n"; 01875 ofs << L"\t\tacceptingkind CDATA #IMPLIED\n"; 01876 ofs << L"\t\tparadigmnamehint CDATA #IMPLIED\n"; // just for compatibility with raw copied data 01877 ofs << L"\t>\n"; 01878 ofs << L"]>\n\n"; 01879 01880 StartElem(_T("clipboard")); 01881 Attr(_T("closureversion"), version_string); 01882 Attr(_T("acceptingkind"), CComBstrObj( acceptingkinds)); 01883 01884 for( CComObjPtrVector<IMgaFolder>::iterator j = parentless_folders.begin(); j != parentless_folders.end(); ++j ) 01885 { 01886 CComBSTR path; 01887 01888 CComObjPtr<IMgaFolder> parent; 01889 COMTHROW( (*j)->get_ParentFolder( PutOut( parent))); 01890 if ( parent) // it has a folder parent 01891 COMTHROW( parent->get_AbsPath( &path)); 01892 // else: a parentless_folder is the rootfolder, so the path = ""; 01893 01894 //CopyTo( path, m_curTopPath);// m_curTopPath will be used to dump the relative path in "closurename" attr 01895 01896 Dump( *j); 01897 } 01898 01899 for( CComObjPtrVector<IMgaFCO>::iterator i = parentless_fcos.begin() ; i != parentless_fcos.end(); ++i ) 01900 { 01901 CComBSTR path; 01902 01903 CComObjPtr<IMgaModel> parent; 01904 COMTHROW( (*i)->get_ParentModel( PutOut( parent))); 01905 if ( parent) // it has a model parent 01906 COMTHROW( parent->get_AbsPath( &path)); 01907 else // it may be contained by a folder 01908 { 01909 CComObjPtr<IMgaFolder> parent; 01910 COMTHROW( (*i)->get_ParentFolder( PutOut( parent))); 01911 if ( parent) // it has a folder parent 01912 COMTHROW( parent->get_AbsPath( &path)); 01913 else // what the heck! (a parentless fco cannot be the rootfolder) 01914 ASSERT(0); 01915 } 01916 01917 01918 //CopyTo( path, m_curTopPath);// m_curTopPath will be used to dump the relative path in "closurename" attr 01919 01920 Dump( *i); 01921 } 01922 01923 EndElem(); 01924 01925 DoneDump(false); 01926 } 01927 COMCATCH( DoneDump(true); ) 01928 01929 m_selFcos.clear(); 01930 m_selFolders.clear(); 01931 } 01932 01933 void CMgaDumper::DumpConnDetails( CComObjPtr<IMgaConnection> connection) 01934 { 01935 const TCHAR * role_attr [] = { _T("smart0Role=") , _T("smart1Role=") }; 01936 const TCHAR * targetGUID_attr [] = { _T("smart0TargetGUID=") , _T("smart1TargetGUID=") }; 01937 const TCHAR * target_attr [] = { _T("smart0Target=") , _T("smart1Target=") }; 01938 const TCHAR * refchainGUID_attr[]= { _T("smart0RefChainGUID=") , _T("smart1RefChainGUID=") }; 01939 const TCHAR * refchain_attr [] = { _T("smart0RefChain=") , _T("smart1RefChain=") }; 01940 const TCHAR * isbound_attr [] = { _T("smart0IsBound=") , _T("smart1IsBound=") }; 01941 01942 std::tstring array[2]; // { source_info, destin_info }; 01943 CComObjPtrVector<IMgaConnPoint> cps; 01944 COMTHROW( connection->get_ConnPoints( PutOut( cps))); 01945 01946 if( 2 == cps.size()) 01947 { 01948 for( unsigned int i = 0; i < cps.size(); ++i) 01949 { 01950 CComBSTR role_bstr;std::tstring role_str; 01951 COMTHROW( cps[i]->get_ConnRole( &role_bstr)); 01952 int w = 0; // which? 01953 if( role_bstr == CComBSTR(L"dst")) w = 1; // otherwise will fill arr[0] 01954 CopyTo( role_bstr, role_str); 01955 01956 array[w] += std::tstring( role_attr[w]) + _T("\"") + role_str + _T("\" "); 01957 01958 CComObjPtr<IMgaFCO> target; 01959 COMTHROW( cps[i]->get_Target(PutOut(target)) ); 01960 01961 if( target == NULL ) 01962 HR_THROW(E_INVALID_MGA); 01963 01964 CComBSTR guid; 01965 COMTHROW( target->get_RegistryValue( CComBSTR(GLOBAL_ID_STR), &guid)); 01966 if( guid != 0 && guid.Length() == GLOBAL_ID_LEN) // valid 01967 { 01968 std::tstring guid_str; CopyTo( guid, guid_str); 01969 array[w] += std::tstring( targetGUID_attr[w]) + _T("\"") + guid_str + _T("\" "); 01970 } 01971 01972 CComBSTR nameBstr; 01973 COMTHROW( connection->get_AbsPath( &nameBstr)); 01974 CopyTo( nameBstr, m_currAbsPath); // will be used by the DumpConnPoint also 01975 01976 nameBstr.Empty(); 01977 std::tstring t_name; 01978 COMTHROW( target->get_AbsPath( &nameBstr)); 01979 CopyTo( nameBstr, t_name); 01980 01981 //Attr("closure2target", makeRel( t_name, m_currAbsPath)); 01982 std::tstring relpath_to_end = makeRel( t_name, m_currAbsPath); 01983 ASSERT( relpath_to_end.substr(0, 4) == _T("/@..")); 01984 // the path to connection end is calculated relative to the connection 01985 // so if we cut off the first node, then it will be relative to the container 01986 array[w] += std::tstring( target_attr[w]) + _T("\"") + relpath_to_end.substr(4) + _T("\" "); 01987 01988 CComObjPtrVector<IMgaFCO> refs; 01989 COMTHROW( cps[i]->get_References(PutOut(refs)) ); 01990 01991 std::tstring guidrefs = DumpGUIDRefs( refs); 01992 if( !guidrefs.empty()) array[w] += std::tstring( refchainGUID_attr[w]) + _T("\"") + guidrefs + _T("\" "); 01993 01994 std::tstring chain; 01995 for( CComObjPtrVector<IMgaFCO>::iterator j = refs.begin(); j != refs.end(); ++j) 01996 { 01997 CComBSTR name; 01998 COMTHROW( (*j)->get_AbsPath( &name)); 01999 std::tstring nm; 02000 CopyTo( name, nm); 02001 02002 if( !chain.empty() ) 02003 chain += ' '; 02004 02005 std::tstring rel_path_to = makeRel( nm, m_currAbsPath); 02006 ASSERT( rel_path_to.substr( 0, 4) == _T("/@..")); 02007 // rel path converted from relative to the m_currAbsPath to relative to the container 02008 chain += rel_path_to.substr(4); 02009 } 02010 02011 array[w] += std::tstring( refchain_attr[w]) + _T("\"") + chain + _T("\" "); 02012 02013 CComObjPtr<IMgaFCO> base; 02014 COMTHROW( connection->get_DerivedFrom(PutOut(base))); 02015 if(base) { 02016 short stat; 02017 COMTHROW( connection->CompareToBase( cps[i], &stat)); 02018 if(!stat) { 02019 //Attr("isbound", "yes" ); 02020 array[w] += std::tstring( isbound_attr[w]) + _T("\"yes\" "); 02021 } 02022 } 02023 } 02024 02025 if( !array[0].empty()) ofs << " " << array[0] << " "; //the attr names are already in the string 02026 if( !array[1].empty()) ofs << " " << array[1] << " "; 02027 } 02028 }