GME
13
|
00001 #pragma once 00002 00003 #include <map> 00004 #include <vector> 00005 class BinGuid; 00006 class Reporter; 00007 00008 class Typedefs 00009 { 00010 public: // typedefs 00011 typedef std::vector< CoreObj > LIBVEC; 00012 typedef LIBVEC::iterator LIBVEC_ITER; 00013 typedef LIBVEC::const_iterator LIBVEC_CITER; 00014 00015 typedef std::map< BinGuid, LIBVEC > LIBMAP; 00016 typedef LIBMAP::iterator LIBMAP_ITER; 00017 typedef LIBMAP::const_iterator LIBMAP_CITER; 00018 00019 typedef std::vector< std::pair< CoreObj, CoreObj > > LIBPAIRVEC; 00020 typedef LIBPAIRVEC::iterator LIBPAIRVEC_ITER; 00021 }; 00022 00023 class PointerFixup 00024 { 00025 coreobjpairhash identity_map; 00026 00027 typedef struct 00028 { 00029 CoreObj target; 00030 CoreObj created; 00031 attrid_type attrid; 00032 bool redirectable; 00033 } resolve_entry; 00034 00035 std::vector<resolve_entry> resolve_entries; 00036 00037 bool m_isOptimizing; 00038 Typedefs::LIBPAIRVEC m_libPairs; 00039 00040 public: 00041 PointerFixup(); 00042 void setLibPairs( Typedefs::LIBPAIRVEC& p_libPairs); 00043 00044 CoreObj findLibRoot( const CoreObj& p_elem); 00045 CoreObj findCounterpart( const CoreObj& p_libElem); 00046 CoreObj cntPartLib( const CoreObj& p_lib2); 00047 00048 inline void identify(const CoreObj &original, const CoreObj &created) 00049 { 00050 ASSERT( original != NULL && created != NULL ); 00051 00052 identity_map.insert(coreobjpairhash::value_type(original, created)); 00053 } 00054 00055 void resolve(const CoreObj &original, const CoreObj &created, 00056 attrid_type attrid, bool p_skipThis) 00057 { 00058 if( LINKREF_ATTR(attrid) ) 00059 return; 00060 00061 CoreObj target = original[attrid]; 00062 if( target == NULL ) 00063 return; 00064 00065 // if lib1 to be imported contains a lib2 00066 // while the project contains already 00067 // a copy of lib2 (as a standalone lib) 00068 // there is a possibility for optimization 00069 // 00070 // if pointer is in lib1 and tgt in lib2, then 00071 // pointer of lib1 might be redirected to lib2's 00072 // existing counterpart in project (lib2copy) 00073 coreobjpairhash::iterator i = identity_map.find(target); 00074 if( i != identity_map.end() ) 00075 { 00076 if( p_skipThis) 00077 { 00078 #ifdef _DEBUG 00079 //CComBSTR m; 00080 //if( original.IsFCO()) 00081 //{ 00082 // m.Append( original[ATTRID_NAME]);m.Append( "="); 00083 // m.Append( created[ATTRID_NAME]);m.Append( "."); 00084 // m.Append( target[ATTRID_NAME]); m.Append( " found in lib: "); 00085 // CoreObj n = findLibRoot( original); 00086 // if( n) 00087 // m.Append( n[ATTRID_NAME]); m.Append( ";"); 00088 //} 00089 #endif 00090 00091 created[attrid] = i->second;// already created 00092 return; 00093 } 00094 00095 CoreObj iseccnpart; 00096 00097 if( m_isOptimizing) 00098 { 00099 // i->second might be replaced by its counterpart 00100 // in lib2copy 00101 if( i->second.IsFCO() && i->second.GetMetaID() != DTID_CONNECTION) 00102 iseccnpart = findCounterpart( i->second); 00103 // attempts to postpone the decison about these: 00104 else 00105 { 00106 #ifdef _DEBUG 00107 CComBSTR m; 00108 if( i->second.IsFCO()) 00109 { 00110 m.Append( original[ATTRID_NAME]);m.Append( "="); 00111 m.Append( created[ATTRID_NAME]);m.Append( "."); 00112 m.Append( target[ATTRID_NAME]); m.Append( ";"); 00113 } 00114 else 00115 { 00116 CComBSTR m; 00117 m.Append( CoreObj(original).GetMgaObj()[ATTRID_NAME]); 00118 m.Append( "."); 00119 } 00120 #endif 00121 resolve_entry entry; 00122 entry.target = target; 00123 entry.created = created; 00124 entry.attrid = attrid; 00125 entry.redirectable = true; 00126 resolve_entries.push_back(entry); 00127 return; 00128 } 00129 } 00130 00131 if( iseccnpart) 00132 { 00133 created[attrid] = iseccnpart; 00134 } 00135 else 00136 { 00137 created[attrid] = i->second;// already created 00138 #ifdef _DEBUG 00139 //CoreObj tgt = i->second; 00140 //CComBSTR m; 00141 //if( created.IsFCO()) 00142 //{ 00143 // ObjForCore( created)->get_ID( &m); 00144 // m.Append( "."); 00145 // m.Append( created[ATTRID_NAME]); 00146 // if( tgt.IsFCO()) 00147 // m.Append( tgt[ATTRID_NAME]); 00148 // else 00149 // m.Append( tgt.GetMgaObj()[ATTRID_NAME]); 00150 // m.Append( "/"); 00151 //} 00152 //else 00153 //{ 00154 // /*CoreObj& p = created.GetMgaObj(); 00155 // ObjForCore( p)->get_ID( &m); 00156 // m.Append( "{"); 00157 // m.Append( p[ATTRID_NAME]);*/ 00158 // if( tgt.IsFCO()) 00159 // m.Append( tgt[ATTRID_NAME]); 00160 // else 00161 // m.Append( tgt.GetMgaObj()[ATTRID_NAME]); 00162 // m.Append( "}"); 00163 //} 00164 #endif 00165 } 00166 } 00167 else // resolve it later 00168 { 00169 resolve_entry entry; 00170 entry.target = target; 00171 entry.created = created; 00172 entry.attrid = attrid; 00173 entry.redirectable = !p_skipThis; 00174 resolve_entries.push_back(entry); 00175 } 00176 } 00177 00178 inline void clear() 00179 { 00180 resolve_entries.clear(); 00181 identity_map.clear(); 00182 m_libPairs.clear(); 00183 } 00184 00185 void fixPointers() 00186 { 00187 std::vector<resolve_entry>::const_iterator i = resolve_entries.begin(); 00188 while( i != resolve_entries.end() ) 00189 { 00190 CoreObj& new_target = identity_map[i->target]; 00191 00192 try { 00193 ASSERT( new_target != NULL ); 00194 00195 CoreObj iseccnpart; 00196 if( m_isOptimizing) 00197 { 00198 // look for the element's peer in the peer library 00199 if( new_target.IsFCO() && new_target.GetMetaID() != DTID_CONNECTION) 00200 { 00201 iseccnpart = findCounterpart( new_target); 00202 } 00203 if( new_target.IsFCO() && new_target.GetMetaID() == DTID_CONNECTION) 00204 { 00205 iseccnpart = findCounterpart( new_target); 00206 } 00207 } 00208 00209 if( m_isOptimizing && i->redirectable) 00210 { 00211 if( iseccnpart) 00212 (i->created)[i->attrid] = iseccnpart; 00213 else 00214 (i->created)[i->attrid] = new_target; 00215 00216 // diagnostics 00217 #ifdef _DEBUG 00218 //if( !iseccnpart && new_target) // iseccnpart = 0, new_target != 0 00219 //{ 00220 // CComBSTR nm, id; 00221 // CoreObj mp; 00222 // if( new_target.IsFCO()) 00223 // { 00224 // nm = new_target[ATTRID_NAME]; 00225 // ObjForCore( new_target)->get_ID( &id); 00226 // 00227 // } 00228 // else if( mp = new_target.GetMgaObj()) 00229 // { 00230 // nm = mp[ATTRID_NAME]; 00231 // ObjForCore( mp)->get_ID( &id); 00232 // } 00233 // else 00234 // { 00235 // nm = "Null"; 00236 // } 00237 // CComBSTR msg( "Resolution error at "); 00238 // msg.Append( nm); 00239 // msg.Append( " with "); 00240 // msg.Append( id); 00241 //} 00242 #endif 00243 } 00244 else 00245 (i->created)[i->attrid] = new_target; 00246 } catch(...) 00247 { 00248 #ifdef _DEBUG 00249 //CComBSTR nm, id; 00250 //CoreObj mp; 00251 //if( new_target.IsFCO()) 00252 //{ 00253 // nm = new_target[ATTRID_NAME]; 00254 // ObjForCore( new_target)->get_ID( &id); 00255 // 00256 //} 00257 //else if( mp = new_target.GetMgaObj()) 00258 //{ 00259 // nm = mp[ATTRID_NAME]; 00260 // ObjForCore( mp)->get_ID( &id); 00261 //} 00262 //else 00263 //{ 00264 // nm = "Null"; 00265 //} 00266 //CComBSTR msg( "Resolution error at "); 00267 //msg.Append( nm); 00268 //msg.Append( " with "); 00269 //msg.Append( id); 00270 #endif 00271 } 00272 00273 ++i; 00274 } 00275 00276 // deal with connections now 00277 i = resolve_entries.begin(); 00278 while( i != resolve_entries.end() ) 00279 { 00280 CoreObj& new_target = identity_map[i->target]; 00281 ASSERT( new_target != NULL ); 00282 00283 CoreObj iseccnpart; 00284 if( m_isOptimizing && i->redirectable) 00285 { 00286 try 00287 { 00288 if( !new_target.IsFCO() && new_target.GetMgaObj().GetMetaID() == DTID_CONNECTION) 00289 { 00290 // needs to be dealt with: 00291 // in case of DTID_CONNROLE: XREF and MASTEROBJ 00292 // 00293 int mid = new_target.GetMetaID(); 00294 int nid = i->created.GetMetaID(); 00295 if( DTID_CONNROLE == nid) // 107 00296 { 00297 ASSERT( mid == nid); 00298 if( ATTRID_MASTEROBJ == i->attrid) // 517 00299 { 00300 CoreObj g = i->created; 00301 CoreObj derd_conn = g.GetMgaObj(); 00302 CoreObj base_con1 = new_target.GetMgaObj(); 00303 CoreObj base_con2 = findCounterpart( base_con1); 00304 #ifdef _DEBUG 00305 CComBSTR idofcon2, nmofcon2; 00306 if( base_con2) 00307 { 00308 nmofcon2 = base_con2[ATTRID_NAME]; 00309 ObjForCore( base_con2)->get_ID( &idofcon2); 00310 } 00311 00312 COMTHROW(idofcon2.Append( ";")); 00313 COMTHROW(idofcon2.AppendBSTR( nmofcon2)); 00314 COMTHROW(idofcon2.Append( ".")); 00315 #endif 00316 CoreObj role_cntpt; 00317 if( base_con2) 00318 findConnRoleCounterpart( new_target, base_con1, base_con2, role_cntpt); 00319 00320 if( role_cntpt) 00321 { 00322 // 00323 (i->created)[i->attrid] = role_cntpt; 00324 } 00325 else 00326 { 00327 // what to do with unconnectible connections? 00328 #ifdef _DEBUG 00329 CComBSTR nm, id; 00330 CoreObj mp; 00331 if( new_target.IsFCO()) 00332 { 00333 nm = new_target[ATTRID_NAME]; 00334 ObjForCore( new_target)->get_ID( &id); 00335 00336 } 00337 else if( mp = new_target.GetMgaObj()) 00338 { 00339 nm = mp[ATTRID_NAME]; 00340 ObjForCore( mp)->get_ID( &id); 00341 } 00342 else 00343 { 00344 nm = "Null"; 00345 } 00346 CComBSTR msg( "RoleResolution error at "); 00347 msg.Append( nm); 00348 msg.Append( " with "); 00349 msg.Append( id); 00350 #endif 00351 } 00352 } 00353 } 00354 } 00355 00356 } 00357 catch (...) { 00358 #ifdef _DEBUG 00359 CComBSTR nm, id; 00360 CoreObj mp; 00361 if( new_target.IsFCO()) 00362 { 00363 nm = new_target[ATTRID_NAME]; 00364 ObjForCore( new_target)->get_ID( &id); 00365 00366 } 00367 else if( mp = new_target.GetMgaObj()) 00368 { 00369 nm = mp[ATTRID_NAME]; 00370 ObjForCore( mp)->get_ID( &id); 00371 } 00372 else 00373 { 00374 nm = "Null"; 00375 } 00376 CComBSTR msg( "RoleResolution error at "); 00377 msg.Append( nm); 00378 msg.Append( " with "); 00379 msg.Append( id); 00380 #endif 00381 } 00382 } 00383 00384 00385 ++i; 00386 } 00387 00388 clear(); 00389 } 00390 00391 void findConnRoleCounterpart( const CoreObj& p_connRole1, const CoreObj& p_baseConn1, const CoreObj& p_baseConn2, CoreObj& p_connRoleResult) 00392 { 00393 if( !p_connRole1) return; 00394 if( !p_baseConn1) return; 00395 if( !p_baseConn2) return; 00396 00397 CComBSTR cr_rname = p_connRole1[ATTRID_NAME]; 00398 ITERATE_THROUGH( p_baseConn2[ ATTRID_CONNROLE + ATTRID_COLLECTION]) { 00399 CComBSTR it_rname = ITER[ATTRID_NAME]; 00400 if( it_rname == cr_rname) 00401 { 00402 // found: 00403 if( !p_connRoleResult) 00404 p_connRoleResult = ITER; 00405 else 00406 ASSERT(0); // found twice? 00407 } 00408 } 00409 00410 } 00411 }; 00412 00413 class ReplaceDependency // function object 00414 : public std::unary_function<CComBSTR, void> 00415 { 00416 CMgaProject* m_mgaproject; 00417 const CComBSTR& m_lib_id_to_remove; 00418 const CComBSTR& m_lib_id_to_add; 00419 const bool m_incOrIncBy; 00420 00421 public: 00422 ReplaceDependency( CMgaProject* p_mgaproject 00423 , const CComBSTR& p_lib_id_to_remove 00424 , const CComBSTR& p_lib_id_to_add 00425 , bool p_incOrIncBy); 00426 00427 ReplaceDependency::result_type operator()( ReplaceDependency::argument_type p_arg); 00428 }; 00429 00430 class Ozer //Optimizer 00431 { 00432 public: 00433 00434 class StorageMgr // responsible for Storing and Retrieving the information 00435 { 00436 static void writer( CoreObj& p_fldCore 00437 , const CComBSTR& p_node 00438 , const CComBSTR& p_value); 00439 static void reader( CoreObj& p_fldCore 00440 , const CComBSTR& p_node 00441 , CComBSTR& p_value); 00442 public: 00443 static const wchar_t* INCLUDED_BY_STR; 00444 static const wchar_t* INCLUDES_STR; 00445 00446 static void getIncludes( CoreObj& p_fldCore 00447 , CComBSTR& p_idList); 00448 static void setIncludes( CoreObj& p_fldCore 00449 , const CComBSTR& p_idList); 00450 00451 static void getIncludedBy( CoreObj& p_fldCore 00452 , CComBSTR& p_idList); 00453 static void setIncludedBy( CoreObj& p_fldCore 00454 , const CComBSTR& p_idList); 00455 }; 00456 00457 protected: 00458 00459 static bool removeFromList( const CComBSTR& p_erasableVal 00460 , CComBSTR& p_valueList); 00461 00462 static bool addRelation( CoreObj& p_fldCore 00463 , const CComBSTR& p_idToAddToReg 00464 , bool p_incByOrInc); 00465 00466 static bool loseRelation ( CoreObj& p_fldCore 00467 , const CComBSTR& p_idToRemoveFromReg 00468 , bool p_incByOrInc 00469 , bool& p_libraryBecameFree); 00470 00471 public: 00472 00473 class DependentIterator // a dependent library iterator 00474 { 00475 public: 00476 // based on p_incbyOrInc the included or the including libraries are given back 00477 DependentIterator( const CComBSTR& p_list); 00478 DependentIterator( const std::string& p_list); 00479 00480 // traversal methods 00481 bool isDone(); 00482 void next(); 00483 CComBSTR getCurrentBstr(); 00484 std::string getCurrentStr(); 00485 00486 protected: 00487 size_t m_pos; 00488 size_t m_nextPos; 00489 std::string m_tokenizable; 00490 }; 00491 00492 static bool isIncluded( CoreObj& p_fldCore); 00493 00494 00495 static void cutInclusions( CoreObj& p_rootfld 00496 , CoreObj& p_oldLib); 00497 00498 static void copyIncludedBy( CoreObj& p_oldLib 00499 , CoreObj& p_newLib); 00500 00501 static void createDeps( CoreObj& p_lib 00502 , Typedefs::LIBVEC& p_deps); 00503 00504 }; 00505 00506 class LibWorker 00507 { 00508 protected: // members 00509 00510 CMgaProject* m_mgaProject; 00511 CComBSTR m_libName; 00512 bool m_optimized; 00513 00514 void showDetails( CoreObj& p_container, Typedefs::LIBMAP& p_results); 00515 00516 public: 00517 00518 LibWorker( CMgaProject* p_mgaProject 00519 , CComBSTR p_libName 00520 , bool p_optimize); 00521 00522 bool isOptimized() const; 00523 CComBSTR getConnectionStr() const; 00524 CComBSTR getExpandedConnectionStr() const; 00525 00526 void flatten( CoreObj& p_rootfolder 00527 , CoreObj& p_libimgroot 00528 , Typedefs::LIBVEC& p_depLibs); 00529 }; 00530 00531 00532 class LibImgHelper 00533 { 00534 static void discover( int p_recDepth 00535 , CoreObj& p_container 00536 , const CComBSTR& p_avoidThisLib 00537 , Typedefs::LIBMAP& p_results); 00538 00539 00540 public: 00541 // functor class for replacing ObjTreeCopyFromExt with its countless parameters 00542 class DoExtTreeCopy 00543 { 00544 CMgaProject* m_mgaproject; 00545 PointerFixup& m_fixup; // a reference! 00546 Typedefs::LIBPAIRVEC& m_libPairs; // a reference! 00547 Typedefs::LIBVEC& m_superfluousLibs; // a reference! 00548 public: 00549 DoExtTreeCopy( CMgaProject* p_mgaproject 00550 , PointerFixup& p_fixup 00551 , Typedefs::LIBPAIRVEC& p_libPairs 00552 , Typedefs::LIBVEC& p_superfluousLibs); 00553 00554 void operator() ( const CoreObj& p_orig, CoreObj& p_nobj, bool p_indupl); 00555 }; 00556 00557 00558 static void logCreator( CComBSTR& p_log 00559 , const Typedefs::LIBVEC& p_libsToBe 00560 , const Typedefs::LIBVEC& p_libsHosted); 00561 00562 static void matchLibs( const Typedefs::LIBMAP& p_libMap 00563 , const Typedefs::LIBMAP& p_projMap 00564 , Typedefs::LIBPAIRVEC& p_machingPairs 00565 , CComBSTR& p_msgInfo); 00566 00567 static void deleteSuperfluousLibs( Typedefs::LIBVEC& p_superfluousLibs 00568 , Reporter& p_reporter); 00569 00570 static void collectDep( Typedefs::LIBPAIRVEC& p_matchingInfo 00571 , Reporter& p_reporter 00572 , Typedefs::LIBVEC& p_depLibs); 00573 00574 static void ungroupLibs( CoreObj& p_container 00575 , Typedefs::LIBMAP& p_results 00576 , Typedefs::LIBVEC& p_depLibs); 00577 00578 static void recordLibs( bool p_recordAllLibs 00579 , CoreObj& p_container 00580 , Typedefs::LIBMAP& p_results 00581 , const CComBSTR& p_avoidThisLibrary = ""); 00582 00583 static void GetItsGuid( CoreObj& p_coreObj 00584 , BSTR* p_guidDisp); 00585 };