GME  13
MgaLibOps.h
Go to the documentation of this file.
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 };