[GME-commit] GMESRC/GME/Mga MgaLibRefr.cpp,NONE,1.1 MgaLibRefr.h,NONE,1.1 Mga.vcproj,1.1,1.2 MgaCheck.cpp,1.9,1.10 MgaComplexOps.cpp,1.19,1.20 MgaComplexOps.h,1.3,1.4 MgaFCO.cpp,1.35,1.36 MgaFCO.h,1.26,1.27 MgaFolder.cpp,1.32,1.33 MgaGeneric.cpp,1.11,1.12 MgaGeneric.h,1.9,1.10 MgaLibOps.cpp,1.8,1.9 MgaProject.cpp,1.64,1.65

gme-commit at list.isis.vanderbilt.edu gme-commit at list.isis.vanderbilt.edu
Fri May 19 19:35:33 CDT 2006


Update of /project/gme-repository/GMESRC/GME/Mga
In directory escher:/tmp/cvs-serv4132

Modified Files:
	Mga.vcproj MgaCheck.cpp MgaComplexOps.cpp MgaComplexOps.h 
	MgaFCO.cpp MgaFCO.h MgaFolder.cpp MgaGeneric.cpp MgaGeneric.h 
	MgaLibOps.cpp MgaProject.cpp 
Added Files:
	MgaLibRefr.cpp MgaLibRefr.h 
Log Message:
Library Refresh reimplementation.
Library nesting enabled.


CVS User: Zoltan Molnar, ISIS (zolmol)

Index: MgaFolder.cpp
===================================================================
RCS file: /project/gme-repository/GMESRC/GME/Mga/MgaFolder.cpp,v
retrieving revision 1.32
retrieving revision 1.33
diff -C2 -d -r1.32 -r1.33
*** MgaFolder.cpp	15 Nov 2005 20:14:39 -0000	1.32
--- MgaFolder.cpp	19 May 2006 18:35:31 -0000	1.33
***************
*** 31,34 ****
--- 31,35 ----
  		CoreObj  subfolder;
  		COMTHROW(mgaproject->dataproject->CreateObject(DTID_FOLDER,&subfolder.ComPtr()));
+ 		assignGuid( mgaproject, subfolder);
  		assignnewchild(subfolder);
  		metaref_type mr;
***************
*** 388,391 ****
--- 389,393 ----
  
  		COMTHROW(mgaproject->dataproject->CreateObject(tt+DTID_BASE,&fco.ComPtr()));
+ 		assignGuid( mgaproject, fco);
  		assignnewchild(fco);
  		fco[ATTRID_META]=rr;

Index: MgaLibOps.cpp
===================================================================
RCS file: /project/gme-repository/GMESRC/GME/Mga/MgaLibOps.cpp,v
retrieving revision 1.8
retrieving revision 1.9
diff -C2 -d -r1.8 -r1.9
*** MgaLibOps.cpp	13 Oct 2004 15:17:55 -0000	1.8
--- MgaLibOps.cpp	19 May 2006 18:35:31 -0000	1.9
***************
*** 6,9 ****
--- 6,10 ----
  #include "MgaConnection.h"
  #include "MgaLibOps.h" // by ZolMol
+ #include "MgaLibRefr.h"
  
  
***************
*** 24,28 ****
  	ASSERT(newmask == LIBRARY_FLAG || newmask == 0);
  	ITERATE_THROUGH(c[ATTRID_PARENT+ATTRID_COLLECTION]) {
! 		ITER[ATTRID_PERMISSIONS] = (ITER[ATTRID_PERMISSIONS] & INSTANCE_FLAG) | newmask;
  		if(ITER.IsContainer()) setlibpermall(ITER, newmask);
  	}
--- 25,32 ----
  	ASSERT(newmask == LIBRARY_FLAG || newmask == 0);
  	ITERATE_THROUGH(c[ATTRID_PARENT+ATTRID_COLLECTION]) {
! 		if( newmask == 0) // remove all library flags (LIBRARY_FLAG, LIBROOT_FLAG), preserve only INSTANCE
! 			ITER[ATTRID_PERMISSIONS] = ITER[ATTRID_PERMISSIONS] & INSTANCE_FLAG;
! 		else // if applying LIBRARY_FLAG, preserve the LIBROOT_FLAG if previously present
! 			ITER[ATTRID_PERMISSIONS] = (ITER[ATTRID_PERMISSIONS] & (INSTANCE_FLAG|LIBROOT_FLAG)) | newmask;
  		if(ITER.IsContainer()) setlibpermall(ITER, newmask);
  	}
***************
*** 120,124 ****
  	metaid_type s;
  	COMTHROW(mgaproject->dataproject->CreateObject(s = orig.GetMetaID(), &nobj.ComPtr()));
! 	
  	if( s != DTID_REGNODE )		// speedup, no references to regnodes
  		fixup.identify(orig, nobj);
--- 124,128 ----
  	metaid_type s;
  	COMTHROW(mgaproject->dataproject->CreateObject(s = orig.GetMetaID(), &nobj.ComPtr()));
! 
  	if( s != DTID_REGNODE )		// speedup, no references to regnodes
  		fixup.identify(orig, nobj);
***************
*** 141,145 ****
  				if(mvt != VALTYPE_POINTER) {
  					if(ai == ATTRID_PERMISSIONS) {
! 						nobj[ai] = orig[ai] & INSTANCE_FLAG | LIBRARY_FLAG;
  					}
  					else nobj[ai] = static_cast<CComVariant>(orig[ai]);
--- 145,151 ----
  				if(mvt != VALTYPE_POINTER) {
  					if(ai == ATTRID_PERMISSIONS) {
! 						//WAS: nobj[ai] = orig[ai] & INSTANCE_FLAG | LIBRARY_FLAG;
! 						//this way we preserve nested libraries:
! 						nobj[ai] = orig[ai] & (INSTANCE_FLAG|LIBROOT_FLAG) | LIBRARY_FLAG;
  					}
  					else nobj[ai] = static_cast<CComVariant>(orig[ai]);
***************
*** 175,178 ****
--- 181,203 ----
  		COMTHROW(mgaproject->get_MetaGUID(&paradigmGUID));
  
+ 		// ask some info about the project to be attached
+ 		long mga_ver( 0);
+ 		{
+ 			CComBSTR par_nm;     // not used now
+ 			CComBSTR par_vs;     // not used now
+ 			CComVariant par_gd;  // not used now
+ 			VARIANT_BOOL ro_mode;// not used now 
+ 			COMTHROW(p->QueryProjectInfo( connstr, &mga_ver, &par_nm, &par_vs, &par_gd, &ro_mode));
+ 		}
+ 
+ 		// check version of the mga file to be attached
+ 		if( mga_ver < 2)
+ 		{
+ 			MyCComBSTR msg( "Library is in old MGA format. To update please open it as a project, save it and only then can be attached!");
+ 			Reporter( mgaproject).show( msg);
+ 			
+ 			COMTHROW(E_MGA_NOT_SUPPORTED);
+ 		}
+ 
  		COMTHROW(p->OpenEx(connstr, paradigmname, paradigmGUID));
  		COMTHROW(p->BeginTransaction(NULL, TRANSACTION_READ_ONLY));
***************
*** 279,283 ****
  		}
  	}
! 	
  	// PETER : reroute references from the model
  	if (libnode && oldnode.IsFCO()) {
--- 304,308 ----
  		}
  	}
! 
  	// PETER : reroute references from the model
  	if (libnode && oldnode.IsFCO()) {
***************
*** 351,354 ****
--- 376,385 ----
  HRESULT FCO::RefreshLibrary(BSTR libname) {
  	COMTRY_IN_TRANSACTION {
+ 		if( !Identifier::isRefreshableLibRoot( self))
+ 		{
+ 			MyCComBSTR msg( "Inner library can't be refreshed in this project!");
+ 			Reporter( mgaproject).show( msg);
+ 		} else {
+ 
  		CheckWrite();
  		if(!(self[ATTRID_PERMISSIONS] & LIBROOT_FLAG)) {
***************
*** 364,371 ****
  		libimgroot[ATTRID_RELID] = self[ATTRID_RELID];
  
! 		redo_derivs(mgaproject, self, libimgroot, false);
  		inDeleteObject();
! 		docheck(mgaproject);
! 	} COMCATCH_IN_TRANSACTION(;);
  }
  
--- 395,428 ----
  		libimgroot[ATTRID_RELID] = self[ATTRID_RELID];
  
! 		MyCComBSTR msg( "---------------------Library refresh started---------------------");
! 		Reporter( mgaproject).show( msg, false);
! 		
! 		RefreshManager rm( mgaproject, self, libimgroot);
! 		ASSERT( Identifier::isLibRoot( self));
! 
! 		rm.collectDependencies( self);
! 		rm.cutRelations( self);
! 		//redo_derivs(mgaproject, self, libimgroot, false);
! 		rm.restoreDependencies();
! 		rm.clearDepStorage();
! 
  		inDeleteObject();
! 
! 		try {
! 			docheck(mgaproject);
! 
! 			MyCComBSTR msg;
! 			msg.Append( "----------------------Library refresh done--------");
! 			rm.getNumOfErrors( msg);
! 			msg.Append( "--");
! 			Reporter( mgaproject).show( msg, false);
! 
! 		} catch(hresult_exception& ) {
! 			MyCComBSTR msg( "Check failed after refresh!");
! 			Reporter( mgaproject).show( msg);
! 			throw;
! 		}
! 		}
! 	} COMCATCH_IN_TRANSACTION( Reporter(mgaproject).show( MyCComBSTR( "----------------------Library refresh failed----------------------")));
  }
  

Index: Mga.vcproj
===================================================================
RCS file: /project/gme-repository/GMESRC/GME/Mga/Mga.vcproj,v
retrieving revision 1.1
retrieving revision 1.2
diff -C2 -d -r1.1 -r1.2
*** Mga.vcproj	26 Jan 2005 17:30:46 -0000	1.1
--- Mga.vcproj	19 May 2006 18:35:30 -0000	1.2
***************
*** 544,547 ****
--- 544,562 ----
  			</File>
  			<File
+ 				RelativePath=".\MgaLibRefr.cpp">
+ 				<FileConfiguration
+ 					Name="Release|Win32">
+ 					<Tool
+ 						Name="VCCLCompilerTool"
+ 						PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_MBCS;_USRDLL;_ATL_STATIC_REGISTRY;$(NoInherit)"/>
+ 				</FileConfiguration>
+ 				<FileConfiguration
+ 					Name="Debug|Win32">
+ 					<Tool
+ 						Name="VCCLCompilerTool"
+ 						PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_MBCS;_USRDLL;$(NoInherit)"/>
+ 				</FileConfiguration>
+ 			</File>
+ 			<File
  				RelativePath="MgaModel.cpp">
  				<FileConfiguration
***************
*** 707,710 ****
--- 722,731 ----
  			<File
  				RelativePath="MgaGeneric.h">
+ 			</File>
+ 			<File
+ 				RelativePath=".\MgaLibOps.h">
+ 			</File>
+ 			<File
+ 				RelativePath=".\MgaLibRefr.h">
  			</File>
  			<File

Index: MgaComplexOps.h
===================================================================
RCS file: /project/gme-repository/GMESRC/GME/Mga/MgaComplexOps.h,v
retrieving revision 1.3
retrieving revision 1.4
diff -C2 -d -r1.3 -r1.4
*** MgaComplexOps.h	8 May 2006 20:12:55 -0000	1.3
--- MgaComplexOps.h	19 May 2006 18:35:30 -0000	1.4
***************
*** 31,34 ****
--- 31,36 ----
  
  void SingleObjTreeDelete(CoreObj &self, bool deleteself = true); 
+ void assignGuid( CMgaProject *mgaproject, CoreObj& ss);
+ void getMeAGuid( long *p_l1, long *p_l2, long *p_l3, long *p_l4);
  
  #endif //MGACOMPLEXOPS_H_1093481093485091384

Index: MgaFCO.h
===================================================================
RCS file: /project/gme-repository/GMESRC/GME/Mga/MgaFCO.h,v
retrieving revision 1.26
retrieving revision 1.27
diff -C2 -d -r1.26 -r1.27
*** MgaFCO.h	13 Mar 2006 19:08:31 -0000	1.26
--- MgaFCO.h	19 May 2006 18:35:31 -0000	1.27
***************
*** 153,156 ****
--- 153,165 ----
  								{ return inFCO->HasReadOnlyAccess( pReadOnly); }
  
+  STDMETHOD(GetGuid)( long* l1, long* l2, long* l3, long* l4)
+ 								{ return inFCO->GetGuid( l1, l2, l3, l4); }
+  STDMETHOD(PutGuid)( long l1, long l2, long l3, long l4)
+ 								{ return inFCO->PutGuid( l1, l2, l3, l4); }
+  STDMETHOD(GetGuidDisp)( BSTR *guid_str)
+ 								{ return inFCO->GetGuidDisp( guid_str); }
+  STDMETHOD(PutGuidDisp)( BSTR guid_str)
+ 								{ return inFCO->PutGuidDisp( guid_str); }
+ 
   STDMETHOD(get_ChildObjects)(IMgaObjects **pVal) 
  								{ return inFCO->get_ChildObjects(pVal); }
***************
*** 388,391 ****
--- 397,405 ----
  	HRESULT PutReadOnlyAccess( VARIANT_BOOL pReadOnly);
  	HRESULT HasReadOnlyAccess( VARIANT_BOOL *pReadOnly);
+ 
+ 	HRESULT GetGuid( long* l1, long* l2, long* l3, long* l4);
+ 	HRESULT PutGuid( long l1, long l2, long l3, long l4);
+ 	HRESULT GetGuidDisp( BSTR *guid_str);
+ 	HRESULT PutGuidDisp( BSTR guid_str);
  
   	HRESULT get_ChildObjects(IMgaObjects **pVal);

Index: MgaProject.cpp
===================================================================
RCS file: /project/gme-repository/GMESRC/GME/Mga/MgaProject.cpp,v
retrieving revision 1.64
retrieving revision 1.65
diff -C2 -d -r1.64 -r1.65
*** MgaProject.cpp	8 Jun 2005 14:21:42 -0000	1.64
--- MgaProject.cpp	19 May 2006 18:35:31 -0000	1.65
***************
*** 5,8 ****
--- 5,10 ----
  #include "MgaFilter.h"
  #include "stdio.h"
+ #include "MgaComplexOps.h"
+ #include "MgaLibOps.h"
  
  void LockingStart(CComPtr<ICoreProject> &tempproject)	{ 
***************
*** 106,109 ****
--- 108,112 ----
  // create data root things
  		    COMTHROW(dataproject->CreateObject(DTID_FOLDER,&rootfolder.ComPtr()));
+ 			assignGuid( this, rootfolder); // assign a guid to the root folder
  			rootfolder[ATTRID_NAME]    = rootname;
  			rootfolder[ATTRID_FPARENT] = dataroot;
***************
*** 165,172 ****
  		if(opened != CLOSED) COMTHROW(E_MGA_PROJECT_OPEN);
  
! 		mgaversion = 1;
  			// Set generic for meta
  		CComPtr<ICoreMetaProject> genericproject;
! 		CreateCoreMetaProject(genericproject);
  
  		CComVariant connGUID;
--- 168,175 ----
  		if(opened != CLOSED) COMTHROW(E_MGA_PROJECT_OPEN);
  
! 		mgaversion = 2;
  			// Set generic for meta
  		CComPtr<ICoreMetaProject> genericproject;
! 		CreateCoreMetaProject(genericproject, mgaversion > 1);
  
  		CComVariant connGUID;
***************
*** 237,245 ****
  	COMTRY {
  		if(opened != CLOSED) COMTHROW(E_MGA_PROJECT_OPEN);
  		CComBSTR s;
  		CComVariant pGUID;
  		CComBSTR ver;
  		CComPtr<ICoreMetaProject> genericproject;
! 		CreateCoreMetaProject(genericproject);
  		VARIANT_BOOL ro;
  
--- 240,259 ----
  	COMTRY {
  		if(opened != CLOSED) COMTHROW(E_MGA_PROJECT_OPEN);
+ 
+ 		// ask project info
+ 		long mga_ver( 0);
+ 		{
+ 			CComBSTR par_nm;     // not used now
+ 			CComBSTR par_vs;     // not used now
+ 			CComVariant par_gd;  // not used now
+ 			VARIANT_BOOL ro_mode;// not used now 
+ 			COMTHROW(this->QueryProjectInfo( projectname, &mga_ver, &par_nm, &par_vs, &par_gd, &ro_mode));
+ 		}
+ 
  		CComBSTR s;
  		CComVariant pGUID;
  		CComBSTR ver;
  		CComPtr<ICoreMetaProject> genericproject;
! 		CreateCoreMetaProject(genericproject, mga_ver > 1); // different than Open: if in old format it won't update
  		VARIANT_BOOL ro;
  
***************
*** 361,365 ****
  		CComBSTR ver;
  		CComPtr<ICoreMetaProject> genericproject;
! 		CreateCoreMetaProject(genericproject);
  
  		COMTHROW(dataproject->OpenProject(projectname, genericproject, ro_mode));
--- 375,379 ----
  		CComBSTR ver;
  		CComPtr<ICoreMetaProject> genericproject;
! 		CreateCoreMetaProject(genericproject, true); // mgaversion = 2 model created by default
  
  		COMTHROW(dataproject->OpenProject(projectname, genericproject, ro_mode));
***************
*** 389,393 ****
  			throw e;
  		}
! 	
  		if(s.Length()) {
  			if (ver.Length()) {
--- 403,407 ----
  			throw e;
  		}
! 
  		if(s.Length()) {
  			if (ver.Length()) {
***************
*** 436,440 ****
  		COMTHROW(RegisterActiveObject((IMgaProject *)this,CLSID_MgaProject,ACTIVEOBJECT_STRONG,&rot));
  		StartAutoAddOns();
! 	
  		try {
  			COMTHROW(BeginTransaction(lm, TRANSACTION_READ_ONLY));
--- 450,454 ----
  		COMTHROW(RegisterActiveObject((IMgaProject *)this,CLSID_MgaProject,ACTIVEOBJECT_STRONG,&rot));
  		StartAutoAddOns();
! 
  		try {
  			COMTHROW(BeginTransaction(lm, TRANSACTION_READ_ONLY));
***************
*** 475,479 ****
  
  		CComPtr<ICoreMetaProject> genericproject;
! 		CreateCoreMetaProject(genericproject);
  
  		COMTHROW(dp.CoCreateInstance(CLSID_CoreProject));
--- 489,493 ----
  
  		CComPtr<ICoreMetaProject> genericproject;
! 		CreateCoreMetaProject(genericproject); // use mgaversion = 1 project model 
  
  		COMTHROW(dp.CoCreateInstance(CLSID_CoreProject));
***************
*** 1719,1723 ****
    CComPtr<ICoreMetaProject> genericproject;
    COMTRY {
! 	CreateCoreMetaProject(genericproject);
  	COMTHROW(storage.CoCreateInstance(	OLESTR("MGA.CoreRepository")));
  	COMTHROW(storage->put_MetaProject(genericproject));
--- 1733,1737 ----
    CComPtr<ICoreMetaProject> genericproject;
    COMTRY {
! 	CreateCoreMetaProject(genericproject); // use mgaversion = 1 project model
  	COMTHROW(storage.CoCreateInstance(	OLESTR("MGA.CoreRepository")));
  	COMTHROW(storage->put_MetaProject(genericproject));

Index: MgaGeneric.h
===================================================================
RCS file: /project/gme-repository/GMESRC/GME/Mga/MgaGeneric.h,v
retrieving revision 1.9
retrieving revision 1.10
diff -C2 -d -r1.9 -r1.10
*** MgaGeneric.h	13 Mar 2006 19:08:31 -0000	1.9
--- MgaGeneric.h	19 May 2006 18:35:31 -0000	1.10
***************
*** 1,4 ****
  
! void CreateCoreMetaProject(CComPtr<ICoreMetaProject> &project);
  
  
--- 1,4 ----
  
! void CreateCoreMetaProject(CComPtr<ICoreMetaProject> &project, bool v2 = false);
  
  
***************
*** 32,35 ****
--- 32,39 ----
  #define ATTRID_RELID					408
  #define ATTRID_LASTRELID				409
+ #define ATTRID_GUID1					411
+ #define ATTRID_GUID2					412
+ #define ATTRID_GUID3					413
+ #define ATTRID_GUID4					414
  
  #define ATTRID_DERIVED					510

Index: MgaGeneric.cpp
===================================================================
RCS file: /project/gme-repository/GMESRC/GME/Mga/MgaGeneric.cpp,v
retrieving revision 1.11
retrieving revision 1.12
diff -C2 -d -r1.11 -r1.12
*** MgaGeneric.cpp	19 Jul 2004 07:01:00 -0000	1.11
--- MgaGeneric.cpp	19 May 2006 18:35:31 -0000	1.12
***************
*** 1,5 ****
  #include "stdafx.h"
   
! void CreateCoreMetaProject(CComPtr<ICoreMetaProject> &project)
  {
  	ASSERT( project == NULL );
--- 1,5 ----
  #include "stdafx.h"
   
! void CreateCoreMetaProject(CComPtr<ICoreMetaProject> &project, bool v2 /*=false*/)
  {
  	ASSERT( project == NULL );
***************
*** 89,92 ****
--- 89,98 ----
  //////////////////////////////////////////////////////////////////////////////////////
  
+ #define GUID_ATTRS_DEFS \
+ 		{ CREATE_ATTRIBUTE(ATTRID_GUID1, "GUID1", "FCO GUID1",	VALTYPE_LONG);\
+ 		CREATE_ATTRIBUTE(ATTRID_GUID2, "GUID2", "FCO GUID2",	VALTYPE_LONG);\
+ 		CREATE_ATTRIBUTE(ATTRID_GUID3, "GUID3", "FCO GUID3",	VALTYPE_LONG);\
+ 		CREATE_ATTRIBUTE(ATTRID_GUID4, "GUID4", "FCO GUID4",	VALTYPE_LONG);}
+ 
  //FOLDER
  		CREATE_OBJECT(DTID_FOLDER, "Folder", "Template For Folder");
***************
*** 104,107 ****
--- 110,115 ----
  		CREATE_COLLECTION(ATTRID_REGNOWNER, "RegNodes", "Registry Nodes");
  		CREATE_ATTRIBUTE(ATTRID_PERMISSIONS, "Permissions", "Permissions", VALTYPE_LONG);
+ 
+ 		if( v2) GUID_ATTRS_DEFS;
  		CLSID_PUSH(  CLSID_MgaO );  
  		
***************
*** 123,127 ****
  /*		CREATE_COLLECTION(ATTRID_REALOBJECT, "Aliases", "Aliases"); */ \
  		CREATE_ATTRIBUTE(ATTRID_PERMISSIONS, "Permissions", "Permissions", VALTYPE_LONG);
! 		
  //MODEL
  		CREATE_OBJECT(DTID_MODEL, "Model", "Template For Model");
--- 131,135 ----
  /*		CREATE_COLLECTION(ATTRID_REALOBJECT, "Aliases", "Aliases"); */ \
  		CREATE_ATTRIBUTE(ATTRID_PERMISSIONS, "Permissions", "Permissions", VALTYPE_LONG);
! 
  //MODEL
  		CREATE_OBJECT(DTID_MODEL, "Model", "Template For Model");
***************
*** 132,135 ****
--- 140,145 ----
  		CREATE_COLLECTION(ATTRID_PARENT, "Children", "Child Objects");
  		CREATE_ATTRIBUTE(ATTRID_LASTRELID, "LastRelID", "Last Child RelID",	VALTYPE_LONG);
+ 
+ 		if( v2) GUID_ATTRS_DEFS;
  		CLSID_PUSH(  CLSID_MgaO );  
  
***************
*** 138,141 ****
--- 148,152 ----
  		FCO_DEF
  
+ 		if( v2) GUID_ATTRS_DEFS;
  		CLSID_PUSH(  CLSID_MgaO );  
  
***************
*** 149,152 ****
--- 160,165 ----
  		CREATE_COLLECTION(ATTRID_MASTEROBJ, "MasterOf", "Master Of Objects");
  		CREATE_ATTRIBUTE(ATTRID_REFASPECT, "RefAspect", "Ref Aspect", VALTYPE_METAREF);
+ 
+ 		if( v2) GUID_ATTRS_DEFS;
  		CLSID_PUSH(  CLSID_MgaO );  
  		
***************
*** 157,160 ****
--- 170,175 ----
  
  		CREATE_COLLECTION(ATTRID_SETMEMBER, "Members", "Set Members");
+ 
+ 		if( v2) GUID_ATTRS_DEFS;
  		CLSID_PUSH(  CLSID_MgaO );  
  
***************
*** 188,191 ****
--- 203,208 ----
  		
  		CREATE_COLLECTION(ATTRID_CONNROLE, "ConnRoles", "ConnRoles");
+ 
+ 		if( v2) GUID_ATTRS_DEFS;
  		CLSID_PUSH(  CLSID_MgaO );  
  		

Index: MgaFCO.cpp
===================================================================
RCS file: /project/gme-repository/GMESRC/GME/Mga/MgaFCO.cpp,v
retrieving revision 1.35
retrieving revision 1.36
diff -C2 -d -r1.35 -r1.36
*** MgaFCO.cpp	13 Mar 2006 19:08:31 -0000	1.35
--- MgaFCO.cpp	19 May 2006 18:35:30 -0000	1.36
***************
*** 1115,1116 ****
--- 1115,1198 ----
  }
  	
+ HRESULT FCO::GetGuid(long* pl1, long* pl2, long* pl3, long* pl4)
+ {
+ 	COMTRY {
+ 		CheckRead();
+ 		CHECK_OUTPAR( pl1);
+ 		CHECK_OUTPAR( pl2);
+ 		CHECK_OUTPAR( pl3);
+ 		CHECK_OUTPAR( pl4);
+ 
+ 		*pl1 = self[ATTRID_GUID1];
+ 		*pl2 = self[ATTRID_GUID2];
+ 		*pl3 = self[ATTRID_GUID3];
+ 		*pl4 = self[ATTRID_GUID4];
+ 
+ 	} COMCATCH(;)
+ }
+ 
+ HRESULT FCO::PutGuid( long l1, long l2, long l3, long l4)
+ {
+ 	COMTRY_IN_TRANSACTION {
+ 		CheckWrite();
+ 		//ASSERT( self.IsFCO());
+ 		//if( self.IsFCO()) {
+ 		self[ATTRID_GUID1] = l1;
+ 		self[ATTRID_GUID2] = l2;
+ 		self[ATTRID_GUID3] = l3;
+ 		self[ATTRID_GUID4] = l4;
+ 	}  COMCATCH_IN_TRANSACTION(;)
+ }
+ 
+ HRESULT FCO::GetGuidDisp( BSTR *p_pGuidStr)
+ {
+ 	COMTRY {
+ 		CheckRead();
+ 		CHECK_OUTPAR( p_pGuidStr);
+ 		long v1(0), v2(0), v3(0), v4(0);
+ 
+ 		COMTHROW( this->GetGuid( &v1, &v2, &v3, &v4));
+ 
+ 		GUID t_guid;
+ 		t_guid.Data1 = v1;
+ 		t_guid.Data2 = (v2 >> 16);
+ 		t_guid.Data3 = (v2 << 16) >> 16;
+ 		t_guid.Data4[0] = (v3 >> 24);
+ 		t_guid.Data4[1] = (v3 << 8) >> 24;
+ 		t_guid.Data4[2] = (v3 << 16) >> 24;
+ 		t_guid.Data4[3] = (v3 << 24) >> 24;
+ 
+ 		t_guid.Data4[4] = (v4 >> 24);
+ 		t_guid.Data4[5] = (v4 << 8) >> 24;
+ 		t_guid.Data4[6] = (v4 << 16) >> 24;
+ 		t_guid.Data4[7] = (v4 << 24) >> 24;
+ 
+ 		char buff[39];
+ 		sprintf( buff, "{%08lX-%04X-%04x-%02X%02X-%02X%02X%02X%02X%02X%02X}",
+ 			t_guid.Data1, t_guid.Data2, t_guid.Data3,
+ 			t_guid.Data4[0], t_guid.Data4[1], t_guid.Data4[2], t_guid.Data4[3],
+ 			t_guid.Data4[4], t_guid.Data4[5], t_guid.Data4[6], t_guid.Data4[7]);
+ 
+ 		*p_pGuidStr = CComBSTR( buff).Detach();
+ 
+ 	} COMCATCH(;)
+ }
+ 
+ HRESULT FCO::PutGuidDisp( BSTR p_guidStr)
+ {
+ 	COMTRY_IN_TRANSACTION {
+ 		CheckWrite();
+ 		CHECK_INSTRPAR( p_guidStr);
+ 		//self[ATTRID_GUID1] = newVal;
+ 		GUID t_guid;
+ 		CopyTo( p_guidStr, t_guid);
+ 
+ 		long v1 = t_guid.Data1; // Data1: 32 b, Data2, Data 3: 16 b, Data4: 64 bit
+ 		long v2 = (t_guid.Data2 << 16) + t_guid.Data3;
+ 		long v3 = (((((t_guid.Data4[0] << 8) + t_guid.Data4[1]) << 8) + t_guid.Data4[2]) << 8) + t_guid.Data4[3];
+ 		long v4 = (((((t_guid.Data4[4] << 8) + t_guid.Data4[5]) << 8) + t_guid.Data4[6]) << 8) + t_guid.Data4[7];
+ 
+ 		PutGuid( v1, v2, v3, v4);
+ 	}  COMCATCH_IN_TRANSACTION(;)
+ }
+ 

--- NEW FILE: MgaLibRefr.h ---
#ifndef MGALIBREFRESH_H
#define MGALIBREFRESH_H

#define DONT_OPTIMIZE 0

#include <stdio.h>
#include <map>
#include <vector>

// ******************************************************************************
//                             C L A S S  BinGuid
// for representing the globally unique id assigned to each object
// NOTE:
// this class (BinGuid) represents a persistent ID of any MGA object (fco or folder)
// these persistent ids are not changing upon export/import/refresh/detach/reattach
// unlike mga ids which can change upon export-import
// beware that if you import twice the same xme file into separate projects
// then these persistent ids will remain equal in those separate projects
// so if these projects later are altered and thus considered different after a while
// they still might contain objects with the same persistent id (a GUID form id)
// in order to tackle this non-uniqueness the id assigned to the rootfolder (as a folder)
// plays an important role in identifying the scope (the realm where uniqueness applies) 
// of a persistent id
// 
class BinGuid
{
protected:
	long v1;
	long v2;
	long v3;
	long v4;

public:
	BinGuid()
		: v1( 0)
		, v2( 0)
		, v3( 0)
		, v4( 0)
	{ 
	}

	BinGuid( long p1, long p2, long p3, long p4)
		: v1( p1)
		, v2( p2)
		, v3( p3)
		, v4( p4) 
	{
	}

	void Set( long p1, long p2, long p3, long p4)
	{
		v1 = p1;
		v2 = p2;
		v3 = p3;
		v4 = p4;
	}

	bool operator == (const BinGuid& peer) const
	{
		if( v1 != peer.v1) return false; // speed-up

		return ( v1 == peer.v1
			&& v2 == peer.v2
			&& v3 == peer.v3
			&& v4 == peer.v4);
	}

	bool operator != ( const BinGuid& peer) const
	{
		return !( *this == peer);
	}

	bool operator < ( const BinGuid& peer) const 
	{
		if( v1 < peer.v1) return true; // speed-up

		return v1 < peer.v1
			|| v1 == peer.v1 && v2 < peer.v2 
			|| v1 == peer.v1 && v2 == peer.v2 && v3 < peer.v3
			|| v1 == peer.v1 && v2 == peer.v2 && v3 == peer.v3 && v4 < peer.v4;
	}

	void ConvertToStd( GUID& p_guid) const
	{
		const BinGuid &m_guid = *this;
		p_guid.Data1 = m_guid.v1;
		p_guid.Data2 = (m_guid.v2 >> 16);
		p_guid.Data3 = (m_guid.v2 << 16) >> 16;
		p_guid.Data4[0] = (m_guid.v3 >> 24);
		p_guid.Data4[1] = (m_guid.v3 << 8) >> 24;
		p_guid.Data4[2] = (m_guid.v3 << 16) >> 24;
		p_guid.Data4[3] = (m_guid.v3 << 24) >> 24;

		p_guid.Data4[4] = (m_guid.v4 >> 24);
		p_guid.Data4[5] = (m_guid.v4 << 8) >> 24;
		p_guid.Data4[6] = (m_guid.v4 << 16) >> 24;
		p_guid.Data4[7] = (m_guid.v4 << 24) >> 24;
	}
};

// ******************************************************************************
//                             C L A S S  UniqueId
// this class comprises the 
//      -- persistent id of an object and the 
//      -- persistent id of the library's rootfolder 
//
// IMPORTANT: the uniqueness of an fco guid is guarranteed within the scope
//            of a project/rootfolder
class UniqueId
{
public:
	BinGuid objectId;
	BinGuid libId;

	UniqueId()
	{
	}

	UniqueId( const BinGuid& po, const BinGuid& pl)
		: objectId( po)
		, libId( pl)
	{
	}

	void SetObj( const BinGuid& obj)
	{
		objectId = obj;
	}

	void SetLib( const BinGuid& lib)
	{
		libId = lib;
	}

	bool operator == (const UniqueId& peer) const
	{
		return ( libId == peer.libId
			&& objectId == peer.objectId);
	}

	bool operator< ( const UniqueId& peer) const 
	{
		if( objectId < peer.objectId) return true;

		return objectId < peer.objectId
			|| objectId == peer.objectId && libId < peer.libId;
	}
};

// regular project id of 0x0065-00000001 form 
// (it is a temporary id in fact, it might change after an export-import)
// used for identifying objects in the hosting project (where libraries are attached)
typedef CComBSTR PROJ_ID;

struct elem_struct
{
	//
	// an object's project id if the referred object is not in a library
	PROJ_ID    id;

	//
	// an object's persistent id if its a library element
	UniqueId   uid;

	// 
	// this variable indicates whether id or uid is filled
	// if inlib the uid, else id is filled
	// we could have used a union as well
	bool       inlib;
};

// ******************************************************************************
//                             C L A S S  MyCComBSTR
// for enhancing CComBSTR with easy output of anchors to objects
// 
class MyCComBSTR : public CComBSTR
{
public:
	MyCComBSTR() : CComBSTR() { }
	MyCComBSTR( const CComBSTR& p) : CComBSTR( p) {}
	
	template<class T>
	void appendLink( const T& ptr)
	{
		appendLink( ObjForCore( CoreObj(ptr)));
	}

	void appendLink( const CComBSTR& id, const CComBSTR& nm = "NonameObject")
	{
		Append("<A HREF=\"mga:");
		AppendBSTR( id);
		Append("\">");
		AppendBSTR( nm);
		Append("</A>");
	}

	void appendLink( FCO* fco)
	{
		CComBSTR id, nm;
		if( fco)
		{
			fco->get_ID( &id);
			fco->get_Name( &nm);
			appendLink( id, nm);
		}
		else
			Append( "NullObject");
	}

	void appendGuid( const GUID& t_guid)
	{
		char buff[39];
		sprintf( buff, "{%08lX-%04X-%04x-%02X%02X-%02X%02X%02X%02X%02X%02X}",
			t_guid.Data1, t_guid.Data2, t_guid.Data3,
			t_guid.Data4[0], t_guid.Data4[1], t_guid.Data4[2], t_guid.Data4[3],
			t_guid.Data4[4], t_guid.Data4[5], t_guid.Data4[6], t_guid.Data4[7]);

		Append( buff);
	}

	void appendGuid( const BinGuid& p_guid)
	{
		GUID t_guid;
		p_guid.ConvertToStd( t_guid);
		
		appendGuid( t_guid);
	}

	void appendGuid( const UniqueId& p_uid)
	{
		appendGuid( p_uid.objectId);
		Append( L" in library ");
		appendGuid( p_uid.libId);
	}
};

// ******************************************************************************
//                             C L A S S  Identifier
// for getting identifying properties about object
//
class Identifier
{
public:
	static BinGuid getPersistentIdOf( const CoreObj& i)
	{
		return BinGuid( i[ATTRID_GUID1], i[ATTRID_GUID2], i[ATTRID_GUID3], i[ATTRID_GUID4]);
	}

	static bool isRefreshableLibRoot( const CoreObj& i)
	{
		// only toplibs can be refreshed (the inner libraries can't)
		bool retv = false;
		retv = getTopLibRootOf( i) == getLibRootOf( i);

		return retv;
	}

	static bool isLibRoot( const CoreObj& i)
	{
		bool retv = false;
		long perm = i[ATTRID_PERMISSIONS];
		ASSERT( perm & LIBROOT_FLAG);
		retv = (perm & LIBROOT_FLAG) != 0;
		
		return retv;
	}

	// gives back the uid of the realm (territory)
	// where the object uid is supposed to be unique
	static BinGuid getLibRootOf( const CoreObj& i)
	{
		CoreObj cur = i;

		bool goon = true;
		while( goon)
		{
			//CComBSTR nm;
			//ObjForCore(cur)->get_Name( &nm);
			//nm.Append(";");

			long perm = cur[ATTRID_PERMISSIONS];
			if( perm & LIBROOT_FLAG)
				return getPersistentIdOf( cur);

			// commented because sometimes regular objects are
			// identified with these helper method:
			// [we must be in a library if LibRoot still not found]
			//ASSERT( perm & LIBRARY_FLAG);

			// if no library element, nor libroot element, must be a regular project
			// element, so we consider these having a BinGuid(0) as their realm uid
			if( (perm & LIBRARY_FLAG) == 0)
				return BinGuid();

			cur = cur[ATTRID_PARENT];
			metaid_type mt = cur.GetMetaID();
			ASSERT( mt != DTID_ROOT);
			goon = cur != 0;// && ( mt != DTID_ROOT);
		}

		return BinGuid();
	}

	// used for getting the uid of the topmost library (the one we 
	// are refreshing now) in case of cascading libraries
	static BinGuid getTopLibRootOf( const CoreObj& i)
	{
		CoreObj cur = i;
		BinGuid lastgood;

		bool goon = true;
		while( goon)
		{
			//CComBSTR nm;
			//ObjForCore(cur)->get_Name( &nm);
			//nm.Append(";");

			long perm = cur[ATTRID_PERMISSIONS];

			if( perm & LIBROOT_FLAG)
				lastgood = getPersistentIdOf( cur);

			cur = cur[ATTRID_PARENT];
			metaid_type mt = cur.GetMetaID();
			//ASSERT( mt != DTID_ROOT);
			goon = cur != 0 && mt != DTID_ROOT;
		}

		return lastgood;
	}

	static UniqueId getDetailsOf( const CoreObj& i)
	{
		UniqueId uid;

		uid.SetObj( getPersistentIdOf( i));
		uid.SetLib( getLibRootOf( i));

		return uid;
	}

	static UniqueId getDetailsOf( const CoreObj& i, BinGuid& pLibCursor)
	{
		UniqueId uid;

		uid.SetObj( getPersistentIdOf( i));
		ASSERT( pLibCursor != BinGuid());
		uid.SetLib( pLibCursor);

		return uid;
	}
};

// ******************************************************************************
//                             C L A S S  Reporter
// sends info and error messages to the console if feature run with GUI
//
class Reporter
{
protected:
	int                 m_counter;
	CComPtr<IGMEOLEApp> m_gme;

	static CComPtr<IGMEOLEApp> get_GME( CMgaProject *p_mgaproject)
	{
		CComPtr<IGMEOLEApp> gme;
		if( p_mgaproject) {		
			CComBSTR bstrName("GME.Application");
			CComPtr<IMgaClient> pClient;
			HRESULT hr = p_mgaproject->GetClientByName(bstrName, &pClient);
			if (SUCCEEDED(hr) && pClient) {
				CComPtr<IDispatch> pDispatch;
				hr = pClient->get_OLEServer(&pDispatch);
				if (SUCCEEDED(hr) && pDispatch) {
					hr = pDispatch.QueryInterface(&gme);
					if (FAILED(hr)) {
						gme = NULL;
					}
				}
			}
		}
		return gme;
	} 

public:

	Reporter( CMgaProject *p_mgaproject) 
		: m_counter( 0)
	{
		m_gme = get_GME( p_mgaproject);
	}

	void show( CComBSTR msg, bool error = true )
	{
		if( error) ++m_counter;
		if( m_gme)
		{
			m_gme->ConsoleMessage( msg, error?MSG_ERROR:MSG_INFO);
		}
	}

	int getErrors() const
	{
		return m_counter;
	}

	static void showIt( CMgaProject *p_mgaproject, CComBSTR msg, bool error = true )
	{
		CComPtr<IGMEOLEApp> t_gme = get_GME( p_mgaproject);

		if( t_gme)
		{
			t_gme->ConsoleMessage( msg, error?MSG_ERROR:MSG_INFO);
		}
	}
};

// ******************************************************************************
//                             C L A S S  SearchTool
// for searching project objects based on project id
// and library objects based on uid
//
class SearchTool
{
public:
	//static std::list<BinGuid> m_sLibIdStack; // the search position is inside the topmost library right now

	static CComPtr<IMgaFCO> findLibObj(CoreObj& folder, const UniqueId& p_toFind, const BinGuid& p_inLib = BinGuid())
	{
		BinGuid act_lib_cursor = p_inLib;
		long pm = folder[ATTRID_PERMISSIONS];
		if( pm & LIBROOT_FLAG)
		{
			BinGuid act_lib_id = Identifier::getPersistentIdOf( folder);
			//m_sLibIdStack.push_back( act_lib_id);

			act_lib_cursor = act_lib_id;
		}

		//BinGuid lib_cursor;
		//ASSERT( !m_sLibIdStack.empty());
		//if( !m_sLibIdStack.empty()) lib_cursor = m_sLibIdStack.back();

		ITERATE_THROUGH(folder[ATTRID_FCOPARENT+ATTRID_COLLECTION]) 
		{
			if(ITER.IsFCO())
			{
				//UniqueId iters_id = Identifier::getDetailsOf( ITER, lib_cursor);
				UniqueId iters_id = Identifier::getDetailsOf( ITER, act_lib_cursor);
				if( iters_id == p_toFind)
				//if( iters_guid == p_toFind.objectId)
				//if( ITER[ATTRID_GUID1] == p_toFind.v1
				//	&& ITER[ATTRID_GUID2] == p_toFind.v2
				//	&& ITER[ATTRID_GUID3] == p_toFind.v3
				//	&& ITER[ATTRID_GUID4] == p_toFind.v4)
				{
					CComPtr<IMgaFCO> fco;
					ObjForCore(ITER)->getinterface(&fco);
					return fco; // found
				}
			}
			
			if( ITER.IsContainer())
			{
				CComPtr<IMgaFCO> fco = findLibObj(ITER, p_toFind, act_lib_cursor);
				if( fco) return fco; // found
			}
		}
		if( pm & LIBROOT_FLAG)
		{
			//m_sLibIdStack.pop_back(); // pop the library id when finished with depth first search of this branch
		}
		return 0;
	}

	static CComPtr<IMgaFCO> findObjWithDetails( CMgaProject *mgaproject, CoreObj& folder, elem_struct& elem)
	{
		if( elem.inlib)
			return findLibObj( folder, elem.uid);
		else
			return findRegularObj( mgaproject, folder, elem.id);
	}


	static CComPtr<IMgaFCO> findRegularObj(CMgaProject * mgaproject, CoreObj& folder, const PROJ_ID& p_toFind)
	{
		CComPtr<IMgaFCO> res;
		try {
			COMTHROW( mgaproject->GetFCOByID( p_toFind, &res));
		} catch( hresult_exception&) {
			res = CComPtr<IMgaFCO>(0);
		}
		return res;
	}

	static CComPtr<IMgaFolder> findFolInHostProjectWithProjId(CMgaProject * mgaproject, CoreObj& folder, const PROJ_ID& p_toFind)
	{
		CComPtr<IMgaFolder> res;
		try {
			CComPtr<IMgaObject> ro;
			COMTHROW( mgaproject->GetObjectByID( p_toFind, &ro));
			if( ro) COMTHROW( ro.QueryInterface( &res));
		} catch( hresult_exception&) {
			res = CComPtr<IMgaFolder>(0);
		}
		return res;
	}

};


// ******************************************************************************
//                             C L A S S  RefreshManager
// for managing the refresh procedure
//
class RefreshManager
{
public:
	RefreshManager( CMgaProject *p_mgaproject, CoreObj& p_oldRoot, CoreObj& p_newRoot)
		: m_mgaproject( p_mgaproject)
		, m_newLib( p_newRoot)
		, m_oldLib( p_oldRoot)
		, m_reporter( p_mgaproject)
	{
	}

protected:
	CMgaProject * m_mgaproject;
	CoreObj       m_newLib;
	CoreObj       m_oldLib;
	Reporter      m_reporter;

	// for reference recreating
	//typedef std::vector< PROJ_ID > REFERENCES_VEC;
	//typedef std::map< UniqueId, REFERENCES_VEC > REFERENCES_MAP; // KEY: GUID of LibTarget, VALUE: vector of Reference ids, which need to be redirected to LibTarget
	typedef std::vector< CoreObj > CORE_REFERENCES_VEC;
	typedef std::map< UniqueId, CORE_REFERENCES_VEC > REFERENCES_MAP; // KEY: GUID of LibTarget, VALUE: vector of Reference ids, which need to be redirected to LibTarget
	REFERENCES_MAP mapOfReferences;

	typedef std::pair< short, CoreObj>                SORTED_REF_ELEM;

	class RefComp
	{
	public:
		bool operator () ( const std::pair< short, CoreObj>& p1
			            , const std::pair< short, CoreObj>& p2) const
		//bool operator < ( const SORTED_REF_ELEM& p1, const SORTED_REF_ELEM& p2)
		{
			if( p1.first < p2.first) return true;
			else if( p1.first > p2.first) return false;
			else return p1.second < p2.second;
		}
	};

	typedef std::set< SORTED_REF_ELEM, RefComp >      CORE_REFERENCES_SET; // short: the distance from the topmost base
	// by using a pair as the key of the map we make sure that hierarchy
	// of reference is observed, the ones at the top will be set before those
	// at the bottom

	typedef std::map< std::pair<short,UniqueId>, CORE_REFERENCES_SET > DEP_REFERENCES_MAP;
	DEP_REFERENCES_MAP mapOfDependentReferences;

	typedef std::pair< UniqueId, UniqueId >               LIBREF_AND_LIBTARGET;
	typedef std::pair< short, LIBREF_AND_LIBTARGET >      LIB_REFTARG_PAIR;
	// if target is in library then UniqueId identifies it
	// otherwise the CoreObj is the target
	typedef std::pair< UniqueId, CoreObj >                MIXED_TARGET;
	// CoreObj is the regular reference in the project, mixedtarget is its target
	typedef std::pair< CoreObj, MIXED_TARGET>             REGREF_AND_TARGET;
	typedef std::vector< REGREF_AND_TARGET >              CORE_DERD_REF_VEC;
	typedef std::map< LIB_REFTARG_PAIR, CORE_DERD_REF_VEC > ADAPTIVE_REFERENCES_MAP;

	// will store adaptive refs (they must be knowledgable of the fact whether their base 
	// was redirected or not, while they are not attached to them yet)
	ADAPTIVE_REFERENCES_MAP          mapOfAdaptiveReferences;
	
	typedef std::pair< short, CoreObj >                 DIST_AND_REFOBJ;
	typedef std::pair< UniqueId, CoreObj >              MIXED_TARGET2; // these refs might point to the library or to the project
	typedef std::map< DIST_AND_REFOBJ, MIXED_TARGET2>   SPECIAL_MAP; // Key: <levelOfRef, Ref>, Value: <TgtId, TgtObj>

	// will store dependents of adaptive references (they must conform to the adaptive refs
	// while they ARE attached to them)
	SPECIAL_MAP                      mapOfDerdRefsFromAdaptiveRef;

	// will prevent dependents of changed (redirected in library) refs
	// to be restored according to the pre-refresh database
	std::set< CoreObj> m_alreadySetRefs;

	// for subtype recreating 
	struct SUB_PAR
	{
		CComPtr<IMgaFCO> subt_ptr;
#if(0)
		PROJ_ID subt_id; // is this needed at all? YES ! if Detach/Attach procedure is used definitely
		PROJ_ID subt_parent;    //obsolete: // these are NOT needed since Detach/Attach  //CComBSTR subt_parent; // where to recreate the subtype?
		CComBSTR subt_metarole; //obsolete: // these are NOT needed since Detach/Attach 
		bool     parentIsFolder;//obsolete: // these are NOT needed since Detach/Attach 
#endif
		bool     is_instance;
	};

	typedef std::vector< SUB_PAR > SUB_PAR_VEC;
	typedef std::map< UniqueId, SUB_PAR_VEC > SUB_PAR_MAP; // KEY: GUID of LibBase, VALUE: vector of subtype related info, which need to be recreated/rederived from LibBase
	SUB_PAR_MAP mapOfDeriveds;
#if(DONT_OPTIMIZE)
	typedef std::map< PROJ_ID, UniqueId > SEC_DER_MAP; // KEY: ID in secondary derived object, VALUE: GUID of base in library
	SEC_DER_MAP mapOfSecondaryDeriveds;
#endif
	typedef std::map< CComPtr<IMgaFCO>, UniqueId > SEC_DER_NAP;
	SEC_DER_NAP napOfSecondaryDeriveds;

	
	typedef std::map< CoreObj, std::pair< CoreObj, bool > > PRI_MATCHMAKER_MAP; // KEY: DERD Obj, VALUE: pair of <BASE, is_instance>
	PRI_MATCHMAKER_MAP                    m_primMatchMaker; // holds only the primary deriveds

	typedef std::map< CoreObj, CoreObj > CORE_MATCH_MAP;
	CORE_MATCH_MAP                       m_coreMatchMaker;  // holds both primary and secondary deriveds
#if(DONT_OPTIMIZE)
	// OBSOLETE:
	std::map< PROJ_ID, PROJ_ID>          m_matchMaker; // map of ids already matched objects
						                               // prevents assigning the same
						                               // base to two different objects
#endif						

	// 
	// for connection recreating
	typedef std::vector< elem_struct > CHAIN_VEC;
	struct conndetails_struct
	{
		elem_struct end;
		CHAIN_VEC chain;
	};

	struct connEnds_struct
	{
		conndetails_struct src;
		conndetails_struct dst;
		elem_struct        parent_model;
		CComBSTR           role;
		PROJ_ID            connid;//will prevent loopnode duplication
		CComBSTR           connname;
		bool               is_derived;
		int                is_sec_derived;
		bool               is_instance;
		bool               baseConnInLib;
		UniqueId           baseConnId;
		CComBSTR           guid;
		CoreObj            saver; // will save owned Attributes, Regnodes & Constraints
	};

	typedef std::vector< connEnds_struct > CONN_STORAGE;
	CONN_STORAGE conns_stored;


#if(DONT_OPTIMIZE)
	struct connEnds_struct2
	{
		CComPtr<IMgaFCO>        src;
		CComPtr<IMgaFCO>        dst;
		CComPtr<IMgaFCOs>       srcRefs;
		CComPtr<IMgaFCOs>       dstRefs;
		CComPtr<IMgaModel>      par;
		CComPtr<IMgaMetaRole>   mrole;
		CComBSTR                nm;
		CComBSTR                guid;
	};
	typedef std::vector< connEnds_struct2 > CONN_STORAGE2;
	CONN_STORAGE2 conns_to_recreate;
#endif
	struct derConnEnds_struct
	{
		CComPtr<IMgaModel>  base_parent;
		CComPtr<IMgaModel>  derd_parent;
		CComPtr<IMgaConnection>  b_conn; // the base connection (new connection found in library)
		CComPtr<IMgaMetaRole>    b_conn_role;
		connEnds_struct          b_conn_struct;

		CComPtr<IMgaFCO>        src;
		CComPtr<IMgaFCO>        dst;
		CComPtr<IMgaFCOs>       srcRefs;
		CComPtr<IMgaFCOs>       dstRefs;
		CComBSTR                nm;
	};

	typedef std::vector< derConnEnds_struct > DERCONN_STORAGE;
	DERCONN_STORAGE conns_to_derive; // new connections found in base which must be derived into derd

	struct HasThisConn // unary predicate, to search for a connection in the vector based on ID
	{
		HasThisConn( const PROJ_ID& id_to_store) : m_id( id_to_store) { }
		bool operator () (connEnds_struct& peer) { return peer.connid == m_id; }
	private:
		PROJ_ID m_id;
	};

	struct OldConn // unary predicate, to decide whether existed connections that were derived from p_uid
	{
		OldConn( const UniqueId& p_uid) : m_uid( p_uid) { }
		bool operator () ( connEnds_struct& peer) { return peer.baseConnId == m_uid; }
	private:
		UniqueId m_uid;
	};

	// 
	// for recreating connection memberships in sets
	typedef std::vector< PROJ_ID>          PIDVECTOR;
	typedef std::map< PROJ_ID, PIDVECTOR > MEMBERMAP;
	MEMBERMAP m_mapOfMemberships;


	std::list<BinGuid> lib_stack;// this stack maintains the library root's guid 
							// imagine that a library may contain inner libraries
							// and during dependency storage (collectDependencies)
							// we have to know which library contains the element
							// whose guid we are storing
							//
							// element guids are not unique globally
							// <project_guid, element_guid> pair is unique
							// TODO: this project guid changes every time the project
							// is modified (?)

	// -----------------------------COLLECTORS & RESTORERS----------------------------

	void DetachObjFromLibBase( const CoreObj& baseObj, CoreObj& derdObj, coreobjpairhash& crealist, unsigned long nextrelid, bool prim);
	void AttachDerObjs( const CoreObj& baseObj, CoreObj& derdObj, coreobjpairhash& crealist, long instance, bool prim);

	// cuts or detaches libraryderived objects
	void cutDersFromLib( CoreObj& one_fco);
	// does the final reattachment of derived objects
	// to the refreshed base objects (found in the library)
	void reattachSubtypesInstances();// CoreObj& ofolder, CoreObj& nfolder);
	
	// -after the cut we decrease relids to seem consistent
	// (to be consistent with the changed hierarchy)
	// -after the reattach we increase relids to be consistent
	// with the actual restored hierarchy
	void PropObjRelidDecrease( CoreObj& orig, long level = 0);
	void PropObjRelidIncrease( CoreObj& orig);

	// aggregates objects in the project which are 
	// derived from library objects
	void saveTopAdaptiveRef( CoreObj& one_ref, CoreObj& bas_ref);
	void saveDerAdaptiveRef( CoreObj& one_ref);

	void collectRefsDerdFromLib( CoreObj& one_ref, CoreObj& bas_ref);
	void collectDersFromLib  ( CoreObj& one_fco);
	void syncStructureFromLib();

	// propagates any change in the base object
	// into subtypes aggregated by collectDersFromLib
	void SyncDerObjs( const CoreObj &freshMasterObj, CoreObj &adaptiveObj, coreobjpairhash &crealist, long instance, bool prim, const CoreObj &priMasterObj, const CoreObj &priAdaptiveObj);
	void SyncObjectName( const CoreObj& p_masterObj, CoreObj &p_adaptiveObj);
	void SyncDerSets( const CoreObj &freshMasterSet, CoreObj &adaptiveSet, const CoreObj &freshMasterPar, CoreObj &adaptivePar);
	void SyncDerRefs( const CoreObj &freshMasterRef, CoreObj &adaptiveRef, const CoreObj &priFreshMasterPar, const CoreObj &priAdaptivePar);


	// aggregates references which are in the project
	// and are directed towards the library
	void collectRefsToLib( CoreObj& one_fco);
	void restoreRefsToLib();
	
	// adapts library derived refs to the new situation
	void adaptTopRefs();
	void adaptDerRefs();

	// a mixed connection is an archetype connection in the project
	// (it is not a secondary derived connection)
	void collectMixedConns( CoreObj& one_fco);
	void restoreMixedConns( CoreObj& folder);

	// a fresh connection is a newly appeared connection in a library base object
	// which needs to be propagated down into the derived objects in the project
	// so it will become secondary derived
	void collectFreshConnection( const CoreObj& p_coreConn, const CoreObj& p_base, const CoreObj& p_derd);
	void syncFreshConns();// CoreObj& ofolder, CoreObj& nfolder);

	void collectMembershipOfConn( const CComPtr<IMgaConnection>& p_conn, const connEnds_struct& conn_info);
	void restoreMembership( const CComPtr<IMgaFCO>& p_conn, connEnds_struct& conn_info, const CComPtr<IMgaModel>& parent);


	// ----------------------------------HELPERS---------------------------------------

	void getElemDetails( CComPtr<IMgaFCO>& peer, elem_struct& elem);
	void getElemDetails( CoreObj& peer, elem_struct& elem);

	short distance( CoreObj& derd);
	bool isDerivedRef( CComPtr<IMgaFCO>& p_ref, CComPtr<IMgaFCO>& p_tgt, bool *p_fromLib, bool *p_isRedirected, bool *p_isSecondaryDerd);
	bool isSecondaryDerivedRef( CComPtr<IMgaFCO>& p_ref, CComPtr<IMgaFCO>& p_tgt, bool* p_fromLib);
	bool isSecondaryDerivedRefFromLibraryObj( CComPtr<IMgaFCO>& ref, bool *p_pbIsRedirected);

	bool ignoreFurtherRedir ( CComPtr<IMgaReference>& orig, CComPtr<IMgaFCO>& ref_tgt_newlib);
	// todo: convert to CoreObj parameters
	bool redirectRefWithCare( CComPtr<IMgaReference>& orig, CComPtr<IMgaFCO>& ref_tgt_newlib);

	void saveConnection( const CComPtr<IMgaFCO>& p_cn);
	void restoreDeletedConns( CoreObj& nfolder);
	void getConnPointDetails( CComPtr<IMgaConnPoint>& cp, conndetails_struct& det, bool* p_ptrIsDestination);
	void getConnectionDetails       ( CComPtr<IMgaConnection>& owner, connEnds_struct& one_conn);

	void findAmongNecDerd( UniqueId& p_uid, const CComPtr<IMgaModel>& d_par, CComPtr<IMgaFCO>& res);
	void findAmongSecDerd( UniqueId& p_uid, const CComPtr<IMgaModel>& d_par, CComPtr<IMgaFCO>& res);
	void findAmongPriDerd( UniqueId& p_uid, const CComPtr<IMgaModel>& d_par, CComPtr<IMgaFCO>& res);
	void findAmongContained( const CComPtr<IMgaModel>& d_par, const PROJ_ID& p_id, CComPtr<IMgaFCO>& res);
	bool isInside( const CComPtr<IMgaModel>& d_par, const CComPtr<IMgaFCO>& res);

	void askTheMatchMaker( const CComPtr<IMgaFCO>& end, const CComPtr<IMgaModel>& b_par, const CComPtr<IMgaModel>& d_par, CComPtr<IMgaFCO>& n_end, bool checkParentHood);
	void getLibDerdEquiv( const CComPtr<IMgaFCO>& end, const CComPtr<IMgaModel>& b_par, const CComPtr<IMgaModel>& d_par, CComPtr<IMgaFCO>& n_end, bool checkParentHood = true);
	
	void removeObsoleteChildren( const CoreObj& masterObj, CoreObj& adaptiveobj);
	void updateMatchDb( coreobjpairhash& p_creaList);
	// copy a fresh container into the whole subtype tree
	typedef std::vector< std::pair< CoreObj, CoreObj> > SET_CREALIST;
	typedef std::vector< std::pair< CoreObj, CoreObj> > REF_CREALIST;
	void copyNewArrivals( CoreObj& adaptiveobj, std::vector< CoreObj> & newcomers
		, SET_CREALIST& set_crealist, REF_CREALIST& ref_crealist);

	// for mixed connection recreation
	bool buildRefChainColl( CMgaProject *mgaproject, CoreObj& folder, CHAIN_VEC& p_chain, CComPtr<IMgaFCOs>& p_sref_chain);
	bool followRefChain( const CComPtr<IMgaFCOs>& chain, CComPtr<IMgaModel>& final_m);

	// for storing previously owned properties of mixed connections
	void loadSavedStuff( CComPtr<IMgaFCO>& p_nConn, connEnds_struct& p_one_conn);
	void saveOwnedStuff( CComPtr<IMgaConnection>& owner, connEnds_struct& one_conn);

	// for fresh connection recreation
	CComPtr<IMgaModel> nextContainer( CComPtr<IMgaFCO>& ref);
	CComPtr<IMgaFCO>   nextElem( CComPtr<IMgaFCO>& p_ref);

	bool verifyChain( const CComPtr<IMgaModel>& pM
		, const CComPtr<IMgaFCOs>& sref_chain, const CComPtr<IMgaFCO>& s);

	bool findConnEndPeer( const derConnEnds_struct& c_info
		, const CComPtr<IMgaFCOs>& p_origChain, const CComPtr<IMgaFCO>& p_origConnEnd
		,       CComPtr<IMgaFCOs>& p_peerChain,       CComPtr<IMgaFCO>& p_peerConnEnd);

	bool fillConnectionPtrs( const derConnEnds_struct& c_info
		, CComPtr<IMgaFCO>& s, CComPtr<IMgaFCO>& d
		, CComPtr<IMgaFCOs>& s_chain, CComPtr<IMgaFCOs>& d_chain);

	// for both
	void prepareConnErrMsg( const CComPtr<IMgaModel>& pM
			, const CComPtr<IMgaFCO>& s, const CComPtr<IMgaFCO>& d
			, const CComPtr<IMgaFCOs>& sref_chain, const CComPtr<IMgaFCOs>& dref_chain
			, const connEnds_struct& current_i, MyCComBSTR& msg);

public:
	void collectDependencies( CoreObj& p_container);
	void cutRelations( CoreObj& container);
	void restoreDependencies();
	void clearDepStorage();
	int  getNumOfErrors( MyCComBSTR& msg);
};


#endif

Index: MgaComplexOps.cpp
===================================================================
RCS file: /project/gme-repository/GMESRC/GME/Mga/MgaComplexOps.cpp,v
retrieving revision 1.19
retrieving revision 1.20
diff -C2 -d -r1.19 -r1.20
*** MgaComplexOps.cpp	8 May 2006 20:12:55 -0000	1.19
--- MgaComplexOps.cpp	19 May 2006 18:35:30 -0000	1.20
***************
*** 226,229 ****
--- 226,231 ----
  	metaid_type s;
  	COMTHROW(mgaproject->dataproject->CreateObject(s = GetMetaID(self), &nobj.ComPtr()));
+ 	if( s>= DTID_MODEL && s <= DTID_FOLDER)
+ 		assignGuid( mgaproject, nobj);
  	if(s >= DTID_MODEL && s <= DTID_SET) {
  		crealist.insert(coreobjpairhash::value_type(self, nobj));
***************
*** 242,245 ****
--- 244,251 ----
  				// remove library flags from a copy
  				if(ai == ATTRID_PERMISSIONS) nobj[ai] = self[ai] & INSTANCE_FLAG;
+ 				else if( ai == ATTRID_GUID1 // don't copy these
+ 					|| ai == ATTRID_GUID2
+ 					|| ai == ATTRID_GUID3 
+ 					|| ai == ATTRID_GUID4) {}
  				else nobj[ai] = static_cast<CComVariant>(self[ai]);
  			}
***************
*** 264,267 ****
--- 270,274 ----
  	COMTHROW(mgaproject->dataproject->CreateObject(s = GetMetaID(self), &nobj.ComPtr()));
  	if(s >= DTID_MODEL && s <= DTID_FOLDER) {
+ 		assignGuid( mgaproject, nobj);
  		crealist.insert(coreobjpairhash::value_type(self, nobj));
  		setcheck(mgaproject, nobj, CHK_NEW);
***************
*** 352,355 ****
--- 359,363 ----
  //			ATTRID_INSTANCE: set if instance, copied from 'origobj' tree othervise
  //			ATTRID_DERIVED & ATTRID_MASTEROBJ: point to the corresponding object in 'origobj' tree
+ //			ATTRID_GUID1..4, which are assigned new value
  // -- on return the new root object 'newobj' will also be contained in the container of 'origobj'.
  // -- new FCO-s are inserted in 'crealist'
***************
*** 360,363 ****
--- 368,373 ----
  	metaid_type s;
  	COMTHROW(mgaproject->dataproject->CreateObject(s = origobj.GetMetaID(), &newobj.ComPtr()));
+ 	if( s >= DTID_MODEL && s <= DTID_FOLDER)
+ 		assignGuid( mgaproject, newobj); // assigns new value to ATTRID_GUID1..4
  	if(s >= DTID_MODEL && s <= DTID_SET) {
  		crealist.insert(coreobjpairhash::value_type(origobj, newobj));
***************
*** 396,399 ****
--- 406,413 ----
  					newobj[ai] = 0L;
  					break;
+ 				case ATTRID_GUID1: // don't copy these
+ 				case ATTRID_GUID2:
+ 				case ATTRID_GUID3:
+ 				case ATTRID_GUID4: break;
  				default:
  					newobj[ai] = static_cast<CComVariant>(origobj[ai]);
***************
*** 1798,1801 ****
--- 1812,1848 ----
  }
  
+ void getMeAGuid( long *p_l1, long *p_l2, long *p_l3, long *p_l4)
+ {
+ 	GUID t_guid = GUID_NULL;
+ 	COMTHROW(CoCreateGuid(&t_guid));
+ 		
+ 	ASSERT(t_guid != GUID_NULL);
+ 	//char buff[39];
+ 	//sprintf( buff, "{%08lX-%04X-%04x-%02X%02X-%02X%02X%02X%02X%02X%02X}",
+ 	//	t_guid.Data1, t_guid.Data2, t_guid.Data3,
+ 	//	t_guid.Data4[0], t_guid.Data4[1], t_guid.Data4[2], t_guid.Data4[3],
+ 	//	t_guid.Data4[4], t_guid.Data4[5], t_guid.Data4[6], t_guid.Data4[7]);
+ 
+ 	// thus replace the old guid with a new one
+ 	*p_l1 = t_guid.Data1; // Data1: 32 b, Data2, Data 3: 16 b, Data4: 64 bit
+ 	*p_l2 = (t_guid.Data2 << 16) + t_guid.Data3;
+ 	*p_l3 = (((((t_guid.Data4[0] << 8) + t_guid.Data4[1]) << 8) + t_guid.Data4[2]) << 8) + t_guid.Data4[3];
+ 	*p_l4 = (((((t_guid.Data4[4] << 8) + t_guid.Data4[5]) << 8) + t_guid.Data4[6]) << 8) + t_guid.Data4[7];
+ }
+ 
+ void assignGuid( CMgaProject *mgaproject, CoreObj& ss)
+ {
+ 	ASSERT( ss.IsFCO() || ss.IsContainer());
+ 	if( !ss.IsFCO() && !ss.IsContainer()) return;
+ 	//if( mgaproject->mgaversion <= 1) return;
+ 
+ 	long l1(0), l2(0), l3(0), l4(0);
+ 	getMeAGuid( &l1, &l2, &l3, &l4);
+ 
+ 	ss[ATTRID_GUID1] = l1;
+ 	ss[ATTRID_GUID2] = l2;
+ 	ss[ATTRID_GUID3] = l3;
+ 	ss[ATTRID_GUID4] = l4;
+ }
  
  

--- NEW FILE: MgaLibRefr.cpp ---
#include "stdafx.h"
#include "MgaLibRefr.h"
#include "MgaLibOps.h"
#include "MgaComplexOps.h"

#define DONT_OPTIM              0
// defined in MgaLibOps.cpp
void steal(CoreObj &o, CoreObj &n, attrid_type ai);

short RefreshManager::distance( CoreObj& derd)
{
	short res = 0;
	CoreObj cur = derd;
	bool goon = true;
	while( goon)
	{
		CoreObj nxt = cur[ATTRID_DERIVED];
		if( nxt && nxt.IsFCO())
		{
[...3041 lines suppressed...]

	// step 5
	m_reporter.show( CComBSTR("[Step 4] Done."), false);
	m_reporter.show( CComBSTR("[Step 5] Reattaching subtypes and instances..."), false);
	
	reattachSubtypesInstances();

	m_reporter.show( CComBSTR("[Step 5] Refresh done."), false);
}

int RefreshManager::getNumOfErrors( MyCComBSTR& msg)
{
	int k = m_reporter.getErrors();
	char buf[32];
	sprintf( buf, "%d", k);
	msg.Append( L"Warnings: ");
	msg.Append( buf);

	return k;
}
Index: MgaCheck.cpp
===================================================================
RCS file: /project/gme-repository/GMESRC/GME/Mga/MgaCheck.cpp,v
retrieving revision 1.9
retrieving revision 1.10
diff -C2 -d -r1.9 -r1.10
*** MgaCheck.cpp	1 May 2006 17:20:12 -0000	1.9
--- MgaCheck.cpp	19 May 2006 18:35:30 -0000	1.10
***************
*** 197,202 ****
  						self[ATTRID_PERMISSIONS] & EXEMPT_FLAG ) {
  							objtype_enum t2;
! 							COMTHROW(parent->GetParent(NULL, &t2));
! 							if(t2 == OBJTYPE_NULL) stillok = true;
  					}
  					if(!stillok) COMTHROW(E_MGA_META_VIOLATION);
--- 197,209 ----
  						self[ATTRID_PERMISSIONS] & EXEMPT_FLAG ) {
  							objtype_enum t2;
! 							CComPtr<IMgaContainer> p2;
! 							COMTHROW(parent->GetParent( &p2, &t2));
! 							CComBSTR libnm2;
! 							COMTHROW( CComQIPtr<IMgaFolder>(parent)->get_LibraryName( &libnm2));
! 
! 							// stillok will be turned true if
! 							// parent of library is either another library or the rootfolder
! 							if( t2 == OBJTYPE_NULL) stillok = true;
! 							else if( libnm2)        stillok = true;
  					}
  					if(!stillok) COMTHROW(E_MGA_META_VIOLATION);



More information about the GME-commit mailing list