GME  13
MgaParserClosureHelper.cpp
Go to the documentation of this file.
00001 #include "stdafx.h"
00002 #include "Parser.h"
00003 #include "MgaParser.h"
00004 #include <xercesc/util/PlatformUtils.hpp>
00005 #include <xercesc/parsers/SAXParser.hpp>
00006 #include <stdio.h>
00007 
00008 #include "../Common/CommonCollection.h"
00009 #include "../Common/CommonMgaTrukk.h"
00010 //#include <list>//slist
00011 #include "helper.h"
00012 
00013 // goes up in the object hierarchy as indicated by the number of '..'s in 'originalPath' and returns the new parent and remaining path info
00014 void CMgaParser::stepUpInHierarchy( CComObjPtr<IMgaObject>& pCurrentObj, const std::tstring& originalPath, CComObjPtr<IMgaObject>& pNewParent, std::tstring& remainingPath)
00015 {
00016         CComObjPtr<IMgaFCO> cur_fco;
00017         CComObjPtr<IMgaFolder> cur_fld;
00018 
00019         pCurrentObj.QueryInterface( cur_fco);
00020         pCurrentObj.QueryInterface( cur_fld);
00021 
00022         bool isfco = (cur_fco != NULL);
00023 
00024         std::tstring m = originalPath;
00025         
00026         while( m.substr(0,4) == _T("/@.."))
00027         {
00028                 CComObjPtr<IMgaModel> mod;
00029                 if( isfco) COMTHROW( cur_fco->get_ParentModel( PutOut( mod)) );
00030 
00031                 if ( mod)       // has a valid model parent
00032                 {
00033                         cur_fco = mod;
00034                 }
00035                 else            // must have folder parent
00036                 {
00037                         CComObjPtr<IMgaFolder> fold;
00038 
00039                         if( isfco)  COMTHROW( cur_fco->get_ParentFolder( PutOut( fold)) );
00040                         else            COMTHROW( cur_fld->get_ParentFolder( PutOut( fold)) );
00041                         
00042                         if ( fold)
00043                         {
00044                                 isfco = false;
00045                                 cur_fld = fold;
00046                         }
00047                         else // rootfolder reached: wrong path information
00048                         {
00049                                 remainingPath = _T("");
00050                                 return; // pNewParent remains empty
00051                         }
00052                 }
00053                 
00054                 m = m.substr(4);
00055         }
00056         
00057         // no more '..' strings in the originalPath
00058         remainingPath = m;
00059         if (isfco && cur_fco) pNewParent = cur_fco;
00060         else if( cur_fld)     pNewParent = cur_fld;
00061 }
00062 
00063 void CMgaParser::findFCOWithRelPathAndGUID( CComObjPtr<IMgaObject> obj_rel_to, const std::tstring& relpath , const std::tstring& guid, CComObjPtr<IMgaFCO>& pFoundFCO)
00064 {
00065         // rel_path gives an indication how much to step up in the hierarchy
00066         CComObjPtr<IMgaObject> new_parent;
00067         stepUpInHierarchy( obj_rel_to, relpath, new_parent, std::tstring());
00068         if( new_parent) // valid parent
00069                 findFCOWithGUIDInTree( new_parent, guid, pFoundFCO);
00070 }
00071 
00072 
00073 void CMgaParser::findFCOWithGUID( CComObjPtr<IMgaObject> prev, const std::tstring& guid, CComObjPtr<IMgaFCO>& pFoundFco)
00074 {
00075         CComObjPtr<IMgaModel> m;
00076         CComObjPtr<IMgaFolder> f;
00077         prev.QueryInterface( m);
00078         prev.QueryInterface( f);
00079         CComObjPtrVector<IMgaFCO> chld;
00080 
00081         if( m)
00082                 COMTHROW( m->get_ChildFCOs( PutOut( chld)));
00083         else if (f)
00084                 COMTHROW( f->get_ChildFCOs( PutOut( chld)));
00085 
00086         unsigned int i;
00087         for( i = 0; i < chld.size(); ++i)
00088         {
00089                 CComBSTR bstr;
00090                 COMTHROW( chld[i]->get_RegistryValue( CComBSTR( PREV_GLOBAL_ID_STR), &bstr));
00091 
00092                 if( bstr != 0 && bstr.Length() == GLOBAL_ID_LEN) //valid
00093                 {
00094                         if( bstr == CComBSTR( guid.c_str()))
00095                                 break;
00096                 }
00097         }
00098 
00099         if( chld.size() > 0 && i < chld.size()) // found
00100                 pFoundFco = chld[i];
00101 
00102 }
00103 
00104 void CMgaParser::findFCOWithGUIDInTree( CComObjPtr<IMgaObject> pParent, const std::tstring& guid, CComObjPtr<IMgaFCO>& pFoundFCO)
00105 {
00106 #if(1)
00107         // breadth-first
00108         CComObjPtrVector<IMgaObject> queue;
00109         unsigned int curr_i = 0;
00110         queue.push_back( pParent);
00111 
00112         while( !pFoundFCO && curr_i != queue.size())
00113         {
00114                 CComObjPtr<IMgaFolder> qF;
00115                 CComObjPtr<IMgaModel>  qM;
00116                 CComObjPtr<IMgaFCO>    qfco;
00117                 queue[curr_i].QueryInterface( qF);
00118                 queue[curr_i].QueryInterface( qM);
00119                 queue[curr_i].QueryInterface( qfco);
00120 
00121                 // check if the current object has the searched GUID
00122                 CComBSTR bstr;
00123 
00124                 // IMgaObject has no get_RegistryValue property
00125                 if( qF) COMTHROW( qF->get_RegistryValue( CComBSTR( PREV_GLOBAL_ID_STR), &bstr));
00126                 else if( qfco) COMTHROW( qfco->get_RegistryValue( CComBSTR( PREV_GLOBAL_ID_STR), &bstr));
00127 
00128                 if( bstr != 0 && bstr.Length() == GLOBAL_ID_LEN && bstr == CComBSTR( guid.c_str())) //valid and equal
00129                         queue[curr_i].QueryInterface( pFoundFCO); // found if succeeds
00130 
00131                 CComObjPtrVector<IMgaFCO> chld;
00132 
00133                 // in case Folder or Model put some new children into the queue
00134                 if( qF) 
00135                 {
00136                         CComObjPtrVector<IMgaFolder> fols;
00137                         COMTHROW( qF->get_ChildFolders( PutOut( fols)));
00138                         // append the children folders to the end of queue
00139                         for( CComObjPtrVector<IMgaFolder>::const_iterator it = fols.begin(); it != fols.end(); ++it)
00140                                 queue.insert( queue.end(), CComObjPtr<IMgaObject>( *it));
00141                         // there was a migration issue with:
00142                         //queue.insert( queue.end(), fols.begin(), fols.end());
00143 
00144                         COMTHROW( qF->get_ChildFCOs( PutOut( chld)));
00145                 }
00146                 else if ( qM) COMTHROW( qM->get_ChildFCOs( PutOut( chld)));
00147 
00148                 // append the children fcos to the end of queue
00149                 for( CComObjPtrVector<IMgaFCO>::const_iterator it = chld.begin(); it != chld.end(); ++it)
00150                         queue.insert( queue.end(), CComObjPtr<IMgaObject>( *it));
00151                 // there was a migration issue with:
00152                 //queue.insert( queue.end(), chld.begin(), chld.end());
00153 
00154                 ++curr_i;
00155         }
00156 
00157 #else // depth first
00158         CComObjPtr<IMgaFolder> f;
00159         CComObjPtr<IMgaModel>  m;
00160         pParent.QueryInterface( m);
00161         pParent.QueryInterface( f);
00162         
00163         CComObjPtrVector<IMgaFCO> chld;
00164         CComObjPtrVector<IMgaFolder> fols;
00165 
00166         if( m) 
00167                 COMTHROW( m->get_ChildFCOs( PutOut( chld)));
00168         else if (f)     
00169         {
00170                 COMTHROW( f->get_ChildFCOs( PutOut( chld)));
00171                 COMTHROW( f->get_ChildFolders( PutOut( fols)));
00172 
00173         }
00174         
00175         CComBSTR bstr;
00176         // perform a depth-first search
00177         for( unsigned int i = 0; !pFoundFCO && i < chld.size(); ++i)
00178         {
00179                 bstr.Empty();
00180                 COMTHROW( chld[i]->get_RegistryValue( CComBSTR( PREV_GLOBAL_ID_STR), &bstr));
00181 
00182                 if( bstr != 0 && bstr.Length() == GLOBAL_ID_LEN && bstr == CComBSTR( guid.c_str())) //valid and equal
00183                 {
00184                         pFoundFCO = chld[i]; // found
00185                 }
00186         }
00187 
00188         // if not found invoke search for children as well
00189         for( unsigned int i = 0; !pFoundFCO && i < chld.size(); ++i)
00190                 findFCOWithGUIDInTree( CComObjPtr<IMgaObject>( chld[i]), guid, pFoundFCO);
00191         for( unsigned int i = 0; !pFoundFCO && i < fols.size(); ++i)
00192                 findFCOWithGUIDInTree( CComObjPtr<IMgaObject>( fols[i]), guid, pFoundFCO);
00193 #endif
00194 }
00195 
00196 
00197 bool CMgaParser::findObjectIn( const CComObjPtr<IMgaObject>& p_parent, const CComObjPtrVector<IMgaFCO>& p_vec, const attributes_type& p_attributes, CComObjPtr<IMgaFCO>& p_obj, const char p_typeRequested)
00198 {
00199         // if the user invoked "paste closure/smart" then merge is not allowed, do not look for existing objects
00200         if( !m_mergeAllowed) return false; 
00201 
00202         // TODO : use role to narrow search
00203         //std::tstring role_in_clipdata = GetByName(p_attributes, "role");
00204 
00205         std::tstring id_in_clipdata = GetByName(p_attributes, _T("closureguid")); // guid
00206         ASSERT( id_in_clipdata.length() == GLOBAL_ID_LEN); 
00207 
00208         bool found = false;
00209         CComObjPtrVector<IMgaFCO>::const_iterator it = p_vec.begin();
00210         while( it != p_vec.end() && !found)
00211         {
00212                 CComBSTR bstr;
00213                 CComObjPtr<IMgaFCO> i = *it;
00214                 COMTHROW( i->get_RegistryValue( CComBSTR(PREV_GLOBAL_ID_STR), &bstr));
00215                 if( bstr == id_in_clipdata.c_str())
00216                 {
00217                         found = true;
00218                         p_obj = i;
00219                 }
00220                 else
00221                         ++it;
00222         }
00223         if( found && p_obj)
00224         {
00225                 // checking object type
00226                 switch( p_typeRequested) {
00227                         case 'M':
00228                                 {
00229                                         CComObjPtr<IMgaModel> _t_m;
00230                                         COMTHROW( p_obj.QueryInterface( _t_m));
00231                                         found = _t_m != 0;
00232                                         break;
00233                                 }
00234                         case 'A':
00235                                 {
00236                                         CComObjPtr<IMgaAtom> _t_a;
00237                                         COMTHROW( p_obj.QueryInterface( _t_a));
00238                                         found = _t_a != 0;
00239                                         break;
00240                                 }
00241                         case 'R':
00242                                 {
00243                                         CComObjPtr<IMgaReference> _t_r;
00244                                         COMTHROW( p_obj.QueryInterface( _t_r));
00245                                         found = _t_r != 0;
00246                                         break;
00247                                 }
00248                         case 'C':
00249                                 {
00250                                         CComObjPtr<IMgaConnection> _t_c;
00251                                         COMTHROW( p_obj.QueryInterface( _t_c));
00252                                         found = _t_c != 0;
00253                                         break;
00254                                 }
00255                         case 'S':
00256                                 {
00257                                         CComObjPtr<IMgaSet> _t_s;
00258                                         COMTHROW( p_obj.QueryInterface( _t_s));
00259                                         found = _t_s != 0;
00260                                         break;
00261                                 }
00262                         case 'F':
00263                                 {
00264                                         CComObjPtr<IMgaFolder> _t_f;
00265                                         COMTHROW( p_obj.QueryInterface( _t_f));
00266                                         found = _t_f != 0;
00267                                         break;
00268                                 }
00269                         case '*':  // means that we don't know the object's type a priori
00270                         default :
00271                                 {
00272                                         found = p_obj != 0;
00273                                         break;
00274                                 }
00275                 };
00276         }
00277 
00278         if( !found                    // id not stored in registry (or different ids found only)
00279            && p_typeRequested != 'C') // but the names may allow us to merge
00280         {                             // except if Connection (usually having same names)
00281                 const std::tstring* s = 0;
00282                 s = GetByNameX(p_attributes, _T("closurename"));
00283                 if( s != 0 && s->compare(_T("")) != 0)
00284                 {
00285                         CComObjPtr<IMgaObject> obj2;
00286                         findObjOnRelPath( CComObjPtr<IMgaObject>(p_parent), *s, obj2, _T("mergable object"));
00287                         if( obj2) COMTHROW( obj2.QueryInterface( p_obj));
00288                         found = p_obj != 0;
00289                 }
00290         }
00291         return found;
00292 }
00293 
00294 bool CMgaParser::findObject( const CComObjPtr<IMgaModel>& p_prev, const attributes_type& p_attributes, CComObjPtr<IMgaFCO>& p_obj, const char p_typeRequested)
00295 {
00296         CComObjPtrVector<IMgaFCO> chld;
00297         if( GetByNameX( p_attributes, _T("kind")))
00298                 COMTHROW( p_prev->GetChildrenOfKind( PutInBstrAttr(p_attributes, _T("kind")), PutOut( chld)));
00299         else
00300                 COMTHROW(p_prev->get_ChildFCOs( PutOut( chld)));
00301 
00302         return findObjectIn( CComObjPtr<IMgaObject>(p_prev), chld, p_attributes, p_obj, p_typeRequested);
00303 }
00304 
00305 bool CMgaParser::findObject( const CComObjPtr<IMgaFolder>& p_prev, const attributes_type& p_attributes, CComObjPtr<IMgaFCO>& p_obj, const char p_typeRequested)
00306 {
00307         CComObjPtrVector<IMgaFCO> chld;
00308         
00309         if( GetByNameX( p_attributes, _T("kind")))
00310                 COMTHROW( p_prev->GetChildrenOfKind( PutInBstrAttr(p_attributes, _T("kind")), PutOut( chld)));
00311         else
00312                 COMTHROW(p_prev->get_ChildFCOs( PutOut( chld)));
00313 
00314         return findObjectIn( CComObjPtr<IMgaObject>(p_prev), chld, p_attributes, p_obj, p_typeRequested);
00315 }
00316 
00317 bool CMgaParser::findFolderIn( const CComObjPtr<IMgaFolder>& p_prev, const attributes_type& p_attributes, CComObjPtr<IMgaFolder>& p_folder)
00318 {
00319         // if the user invoked ''paste closure/smart'' then merge is not allowed, do not look for existing objects
00320         if( !m_mergeAllowed) return false; 
00321 
00322         CComObjPtrVector<IMgaFolder> chld;
00323         COMTHROW(p_prev->get_ChildFolders( PutOut( chld)));
00324 
00325         std::tstring req_kind = GetByName( p_attributes, _T("kind"));
00326 
00327         std::tstring id_in_clipdata = GetByName(p_attributes, _T("closureguid"));
00328         ASSERT( id_in_clipdata.length() == GLOBAL_ID_LEN);
00329 
00330         bool found = false;
00331         CComObjPtrVector<IMgaFolder>::const_iterator it = chld.begin();
00332         while( it != chld.end() && !found)
00333         {
00334                 CComBSTR bstr;
00335                 CComObjPtr<IMgaFolder> i = *it;
00336                 COMTHROW( i->get_RegistryValue( CComBSTR(PREV_GLOBAL_ID_STR), &bstr)); 
00337                 CComObjPtr<IMgaMetaFolder> i_metaf;
00338                 COMTHROW( i->get_MetaFolder( PutOut( i_metaf)));
00339                 CComBSTR i_kind;
00340                 COMTHROW( i_metaf->get_Name( &i_kind));
00341 
00342                 if( bstr == id_in_clipdata.c_str() && i_kind == req_kind.c_str())
00343                 {
00344                         found = true;
00345                         p_folder = i;
00346                 }
00347                 else
00348                         ++it;
00349         }
00350         if( !found)  // id not stored in registry (or different ids found only)
00351         {           // but the names may allow us to merge
00352                 const std::tstring* s = 0;
00353                 s = GetByNameX(p_attributes, _T("closurename"));
00354                 if( s != 0 && s->compare(_T("")) != 0)
00355                 {
00356                         CComObjPtr<IMgaObject> obj2;
00357                         findObjOnRelPath( CComObjPtr<IMgaObject>(p_prev), *s, obj2, _T("mergable object"));
00358                         if( obj2) COMTHROW( obj2.QueryInterface( p_folder));
00359                         found = p_folder != 0;
00360                 }
00361         }
00362         return found;
00363 }
00364 void CMgaParser::findObjOnAbsPath( CComObjPtr<IMgaProject> p_project, const std::tstring& p_absPath , CComObjPtr<IMgaObject>& p_obj, const std::tstring& text)
00365 {
00366         COMTHROW( p_project->get_ObjectByPath( _bstr_t(p_absPath.c_str()), PutOut( p_obj)) );
00367         if( !p_obj) // if nonunique is allowed
00368         {
00369                 COMTHROW( p_project->get_NthObjectByPath( 0, _bstr_t(p_absPath.c_str()), PutOut( p_obj)) );
00370 
00371                 if( p_obj)
00372                 {
00373                         // name ambiguity exists for sure
00374                         //<!> warning about non uniqueness
00375                         if( m_GME) 
00376                         {
00377                                 CComBSTR bstr;
00378                                 COMTHROW(bstr.Append(_T("Name ambiguity, selected: ")));
00379                                 COMTHROW(bstr.AppendBSTR( makeLink( p_obj)));
00380                                 
00381                                 if( !text.empty())
00382                                 {
00383                                         COMTHROW(bstr.Append(L" as "));
00384                                         COMTHROW(bstr.Append( text.c_str()));
00385                                 }
00386 
00387                                 COMTHROW(bstr.Append(L". Search path used: "));
00388                                 COMTHROW(bstr.Append( makeViewable(p_absPath).c_str()));
00389                                 msgSC( bstr, MSG_WARNING);
00390                         }
00391                 }
00392         }
00393 }
00394 
00395 void CMgaParser::findObjOnRelPath( CComObjPtr<IMgaObject> obj_rel_to, const std::tstring& relpath , CComObjPtr<IMgaObject>& obj, const std::tstring& text)
00396 {
00397         ASSERT( !relpath.empty());
00398         ASSERT( obj_rel_to);
00399 
00400         CComObjPtr<IMgaFCO> cur_fco;
00401         CComObjPtr<IMgaFolder> cur_fld;
00402 
00403         obj_rel_to.QueryInterface( cur_fco);
00404         obj_rel_to.QueryInterface( cur_fld);
00405 
00406         bool isfco = (cur_fco != NULL);
00407 
00408         std::tstring m = relpath;
00409         
00410         while( m.substr(0,4) == _T("/@.."))
00411         {
00412                 CComObjPtr<IMgaModel> mod;
00413                 if( isfco) COMTHROW( cur_fco->get_ParentModel( PutOut( mod)) );
00414 
00415                 if ( mod)       // has a valid model parent
00416                 {
00417                         cur_fco = mod;
00418                 }
00419                 else            // must have folder parent
00420                 {
00421                         CComObjPtr<IMgaFolder> fold;
00422 
00423                         if( isfco)  COMTHROW( cur_fco->get_ParentFolder( PutOut( fold)) );
00424                         else            COMTHROW( cur_fld->get_ParentFolder( PutOut( fold)) );
00425                         
00426                         if ( fold)
00427                         {
00428                                 isfco = false;
00429                                 cur_fld = fold;
00430                         }
00431                         // else rootfolder reached: wrong path information
00432                 }
00433                 
00434                 m = m.substr(4);
00435         }
00436         
00437         if( m.empty())
00438         {
00439                 if (isfco)      obj = cur_fco;
00440                 else            obj = cur_fld;
00441         }
00442         else if( isfco)
00443                 COMTHROW( cur_fco->get_ObjectByPath( PutInBstr( m), PutOut( obj)) );
00444         else
00445                 COMTHROW( cur_fld->get_ObjectByPath( PutInBstr( m), PutOut( obj)) );
00446 
00447         if( !obj) // not found , name ambiguity may exist, take the 1st
00448         {
00449                 if( isfco)
00450                         COMTHROW( cur_fco->get_NthObjectByPath( 0, PutInBstr( m), PutOut( obj)) );
00451                 else
00452                         COMTHROW( cur_fld->get_NthObjectByPath( 0, PutInBstr( m), PutOut( obj)) );
00453 
00454                 if( obj) // name ambiguity exists for sure
00455                 {
00456                         if( m_GME) 
00457                         {
00458                                 CComBSTR bstr;
00459                                 COMTHROW(bstr.Append(L"Name ambiguity, selected: "));
00460                                 COMTHROW(bstr.AppendBSTR( makeLink( obj)));
00461                                 if( !text.empty())
00462                                 {
00463                                         COMTHROW(bstr.Append(L" as "));
00464                                         COMTHROW(bstr.Append( text.c_str()));
00465                                 }
00466 
00467                                 COMTHROW(bstr.Append(L". Search path used: "));
00468                                 COMTHROW(bstr.Append( makeViewable(relpath).c_str()));
00469                                 msgSC( bstr, MSG_WARNING);
00470                         }
00471                 }
00472         }
00473 }
00474 
00475 bool CMgaParser::findPlaceForElem( 
00476                                                              const attributes_type &attributes
00477                                                            , deriv_type& deriv
00478                                                            , CComObjPtr<IMgaObject>& place
00479                                                         )
00480 {
00481         const std::tstring *nm = GetByNameX(attributes, _T("closurepath"));
00482         if( nm != NULL)
00483         {
00484                 if( nm->compare(_T("")) == 0)
00485                 {
00486                         place = m_target;
00487                         return true;
00488                 }
00489                 else
00490                 {
00491                         findObjOnRelPath( m_target, *nm, place, _T("place"));
00492                         if( place)
00493                                 return true;
00494                         else
00495                                 ASSERT(0);
00496                 }
00497         }
00498         return false;
00499 }
00500 
00501 //<!> check if findObjOnRelPath is given "" string
00502 
00503 bool CMgaParser::findPlaceForElem( 
00504                                                              const attributes_type &attributes
00505                                                            , deriv_type& deriv
00506                                                            , CComObjPtr<IMgaFolder>& place_folder
00507                                                            , CComObjPtr<IMgaModel>& place_model
00508                                                         )
00509 {
00510         
00511         CComObjPtr<IMgaObject> place;
00512         if( findPlaceForElem( attributes, deriv, place))
00513         {
00514                 place.QueryInterface( place_folder);
00515                 place.QueryInterface( place_model);
00516                 return (place_folder || place_model);
00517         }
00518         else
00519         {
00520                 place = m_target;//<!> let's try this
00521                 
00522                 CComBSTR bstr("Correct place not found for object: ");
00523                 COMTHROW(bstr.Append( makeNameViewable( GetByName( attributes, _T("closurename"))).c_str()));
00524                 COMTHROW(bstr.Append(". Search path used: "));
00525                 COMTHROW(bstr.Append( makeViewable( GetByName(attributes, _T("closurepath"))).c_str()));
00526                 COMTHROW(bstr.Append(". Trying to insert into the target object: "));
00527                 COMTHROW(bstr.AppendBSTR( makeLink( place)));
00528                 COMTHROW(bstr.Append("."));
00529                 msgSC(bstr, MSG_ERROR);
00530 
00531                 place.QueryInterface( place_folder);
00532                 place.QueryInterface( place_model);
00533                 return (place_folder || place_model);
00534         }
00535         return false;
00536 }
00537 
00538 /*static*/ CComPtr<IGMEOLEApp> CMgaParser::get_GME(CComObjPtr<IMgaProject> project)
00539 {
00540         CComPtr<IGMEOLEApp> gme;
00541         if ( (project != NULL)) {               
00542                 CComBSTR bstrName(L"GME.Application");
00543                 CComPtr<IMgaClient> pClient;
00544                 HRESULT hr = project->GetClientByName(bstrName, &pClient);
00545                 if (SUCCEEDED(hr) && pClient) {
00546                         CComPtr<IDispatch> pDispatch;
00547                         hr = pClient->get_OLEServer(&pDispatch);
00548                         if (SUCCEEDED(hr) && pDispatch) {
00549                                 hr = pDispatch.QueryInterface(&gme);
00550                                 if (FAILED(hr)) {
00551                                         gme = NULL;
00552                                 }
00553                         }
00554                 }
00555         }
00556         return gme;
00557 } 
00558 
00559 /*static*/ void CMgaParser::clear_GME( CComPtr<IGMEOLEApp>& p_GME)
00560 {
00561         p_GME = CComPtr<IGMEOLEApp>();
00562 }
00563 
00564 
00565 bool CMgaParser::isNeedFor2ndStep()
00566 {
00567         return !m_notFoundReferredObject.empty() || !m_notFoundSetMembers.empty();
00568 }
00569 
00570 void CMgaParser::tryToFindMissedReferreds()
00571 {
00572         std::map< CComObjPtr<IMgaFCO>, std::tstring, CompareCComObj >::iterator it = m_notFoundReferredObject.begin();
00573         std::map< CComObjPtr<IMgaFCO>, std::tstring, CompareCComObj >::iterator itend = m_notFoundReferredObject.end();
00574         for( ; it != itend; ++it)
00575         {
00576                 if( !it->first) continue;
00577                 bool error = false;
00578 
00579                 CComObjPtr<IMgaObject> target;
00580                 findObjOnRelPath( CComObjPtr<IMgaObject>( it->first), it->second, target, _T("referred object"));
00581                 if( target)
00582                 {
00583                         CComObjPtr<IMgaReference> ref;
00584                         COMTHROW( it->first.QueryInterface( ref));
00585                         CComObjPtr<IMgaFCO> fco_target;
00586                         COMTHROW( target.QueryInterface( fco_target));
00587 
00588                         if( ref && fco_target)
00589                         {
00590                                 COMTHROW( ref->put_Referred( fco_target));
00591 
00592                                 CComBSTR bstr( "Reference ");
00593                                 COMTHROW(bstr.AppendBSTR( makeLink( ref)));
00594                                 COMTHROW(bstr.Append( " set to refer to "));
00595                                 COMTHROW(bstr.AppendBSTR( makeLink( fco_target)));
00596                                 COMTHROW(bstr.Append(" in 2nd step successfully."));
00597                                 msgSC(bstr, MSG_INFO);
00598                         }
00599                         else
00600                                 error = true;
00601                 }
00602                 else 
00603                         error = true;
00604 
00605                 if( error)
00606                 {
00607                         CComBSTR bstr( "Reference ");
00608                         COMTHROW(bstr.AppendBSTR( makeLink( it->first )));
00609                         COMTHROW(bstr.Append( ": target not found in 2nd step. "));
00610                         COMTHROW(bstr.Append("Search path used: "));
00611                         COMTHROW(bstr.Append( makeViewable( it->second).c_str()));
00612                         msgSC(bstr, MSG_ERROR);
00613                 }
00614         }
00615 }
00616 
00617 void CMgaParser::tryToFindMissedSetMembers()
00618 {
00619         std::map< CComObjPtr<IMgaFCO>, std::vector< std::tstring >, CompareCComObj >::iterator it = m_notFoundSetMembers.begin();
00620         std::map< CComObjPtr<IMgaFCO>, std::vector< std::tstring >, CompareCComObj >::iterator itend = m_notFoundSetMembers.end();
00621         for( ; it != itend; ++it)
00622         {
00623                 if( !it->first || it->second.empty()) continue;
00624 
00625                 CComObjPtr<IMgaSet> set;
00626                 COMTHROW( it->first.QueryInterface( set));
00627 
00628                 if( !set) continue;
00629 
00630                 std::vector< std::tstring >::iterator member_it = it->second.begin();
00631                 std::vector< std::tstring >::iterator member_it_end = it->second.end();
00632                 for( ; member_it != member_it_end; ++member_it)
00633                 {
00634                         if( member_it->empty()) continue;
00635 
00636                         bool error = false;
00637                         CComObjPtr<IMgaObject> member;
00638                         findObjOnRelPath( CComObjPtr<IMgaObject>( it->first), *member_it, member, _T("set member"));
00639                         if( member)
00640                         {
00641                                 CComObjPtr<IMgaFCO> fco_member;
00642                                 COMTHROW( member.QueryInterface( fco_member));
00643 
00644                                 if( fco_member)
00645                                 {
00646                                         COMTHROW( set->AddMember( fco_member));
00647 
00648                                         CComBSTR bstr( "Member");
00649                                         COMTHROW(bstr.AppendBSTR( makeLink( fco_member)));
00650                                         COMTHROW(bstr.Append( " added to set "));
00651                                         COMTHROW(bstr.AppendBSTR( makeLink( set)));
00652                                         COMTHROW(bstr.Append(" in 2nd step successfully."));
00653                                         msgSC(bstr, MSG_INFO);
00654                                 }
00655                                 else
00656                                         error = true;
00657                         }
00658                         else
00659                                 error = true;
00660 
00661                         if( error)
00662                         {
00663                                 CComBSTR bstr( "Set ");
00664                                 COMTHROW(bstr.AppendBSTR( makeLink( set)));
00665                                 COMTHROW(bstr.Append(": member not found in 2nd step. "));
00666                                 COMTHROW(bstr.Append("Search path used: "));
00667                                 COMTHROW(bstr.Append( makeViewable( *member_it).c_str()));
00668                                 msgSC(bstr, MSG_ERROR);
00669                         }
00670                 }
00671         }
00672 }
00673 
00674 /*static*/ bool CMgaParser::isEmptySet( CComObjPtr<IMgaFCO>& fco)
00675 {
00676         bool empty = false;
00677         CComObjPtr<IMgaSet> t_set;
00678         if( fco) 
00679         {
00680                 COMTHROW( fco.QueryInterface( t_set));
00681                 if( t_set) 
00682                 {
00683                         CComObjPtrVector<IMgaFCO> mems;
00684                         COMTHROW( t_set->get_Members( PutOut( mems)));
00685                         if( mems.size() == 0) empty = true;
00686                 }
00687         }
00688         return empty;
00689 }
00690 
00691 /*static*/ bool CMgaParser::isNullRef( CComObjPtr<IMgaFCO>& fco)
00692 {
00693         bool null = false;
00694         CComObjPtr<IMgaReference> t_ref;
00695         ASSERT( fco);
00696         if( fco)
00697         {
00698                 COMTHROW( fco.QueryInterface( t_ref));
00699                 if( t_ref) 
00700                 {
00701                         CComObjPtr<IMgaFCO> referred;
00702                         COMTHROW( t_ref->get_Referred( PutOut(referred)));
00703                         if( !referred) null = true;
00704                 }
00705         }
00706         return null;
00707 }
00708 
00709 void CMgaParser::msgSC( CComBSTR& msg, msgtype_enum type)
00710 {
00711         static const TCHAR * sc_text = _T("[Smartcopy Parser] ");
00712         CComBSTR m2;
00713         std::tstring t;
00714         CopyTo( msg, t);
00715         if( t.substr( 0, _tcslen( sc_text)) != sc_text)
00716         {
00717                 COMTHROW(m2.Append( sc_text));
00718                 COMTHROW(m2.AppendBSTR( msg));
00719         }
00720         else
00721                 m2 = msg;
00722 
00723         if( m_GME) COMTHROW( m_GME->ConsoleMessage( m2, type));
00724 }