GME
13
|
00001 // MgaConnection.cpp : Implementation of CMgaConnection 00002 #include "stdafx.h" 00003 #include "MgaConnection.h" 00004 00006 // CMgaConnection 00007 const CComBSTR FCO::SrcName="src", FCO::DstName="dst"; 00008 00009 00010 bool FCO::findroleobj(BSTR rolename, CoreObj &tt) { 00011 CHECK_INSTRPAR(rolename); 00012 CoreObjs roles = self[ATTRID_CONNROLE+ATTRID_COLLECTION]; 00013 ITERATE_THROUGH(roles) { 00014 CComBSTR n = ITER[ATTRID_NAME]; 00015 if(n == rolename) { 00016 tt <<= ITER; 00017 return true; 00018 } 00019 } 00020 return false; 00021 } 00022 00023 HRESULT FCO::get_NamedRoleReferences(BSTR rolename, IMgaFCOs **pVal) { 00024 COMTRY { 00025 CHECK_INSTRPAR(rolename); 00026 CHECK_OUTPTRPAR(pVal); 00027 CoreObj r; 00028 if(!findroleobj(rolename, r)) 00029 { 00030 COMRETURN(E_MGA_NAME_NOT_FOUND); 00031 } 00032 CoreObjs segs = r[ATTRID_CONNSEG+ATTRID_COLLECTION]; 00033 segs.Sort(); 00034 CREATEEXCOLLECTION_FOR(MgaFCO, q); 00035 ITERATE_THROUGH(segs) { 00036 CoreObj seg = ITER[ATTRID_SEGREF]; 00037 ASSERT(seg); 00038 CComPtr<IMgaFCO> ff; 00039 ObjForCore(seg)->getinterface(&ff); 00040 q->Add(ff); 00041 } 00042 *pVal = q.Detach(); 00043 } COMCATCH(;) 00044 } 00045 00046 HRESULT FCO::get_NamedRoleTarget(BSTR rolename, IMgaFCO **pVal) { 00047 COMTRY { 00048 CHECK_INSTRPAR(rolename); 00049 CHECK_OUTPTRPAR(pVal); 00050 CoreObj r; 00051 if(findroleobj(rolename, r)) { 00052 CoreObj obj = r[ATTRID_XREF]; 00053 if(obj) { 00054 ObjForCore(obj)->getinterface(pVal); 00055 } 00056 } 00057 } COMCATCH(;) 00058 } 00059 00060 00061 HRESULT FCO::put_NamedRole(BSTR rolename, IMgaFCOs *refs, IMgaFCO *endfco) { 00062 COMTRY_IN_TRANSACTION_MAYBE { 00063 CheckWrite(); 00064 { 00065 booltempflag fl(mgaproject->checkofftemporary); 00066 00067 CComPtr<IMgaConnPoints> p; 00068 COMTHROW(get_ConnPoints(&p)); 00069 MGACOLL_ITERATE(IMgaConnPoint, p) { 00070 CComBSTR rn; 00071 COMTHROW(MGACOLL_ITER->get_ConnRole(&rn)); 00072 if(rn == rolename) { 00073 COMTHROW(MGACOLL_ITER->Remove()); 00074 break; 00075 } 00076 } MGACOLL_ITERATE_END; 00077 } 00078 if(endfco) { 00079 CComPtr<IMgaConnPoint> tt; 00080 COMRETURN_IN_TRANSACTION_MAYBE(AddConnPoint(rolename, 1, endfco, refs, &tt)); 00081 } 00082 } COMCATCH_IN_TRANSACTION_MAYBE(;) 00083 } 00084 00085 HRESULT FCO::CreateSimpleConn( IMgaMetaRole *metar, IMgaFCO *src, IMgaFCO *dst, 00086 IMgaFCOs *srcrefs, IMgaFCOs *dstrefs, IMgaFCO **newobj) { 00087 COMTRY_IN_TRANSACTION { 00088 00089 CComPtr<IMgaFCO> f; 00090 { 00091 booltempflag fl(mgaproject->checkofftemporary); 00092 COMTHROW(CreateChildObject(metar, &f)); 00093 objtype_enum ot; 00094 COMTHROW(f->get_ObjType(&ot)); 00095 if(ot != OBJTYPE_CONNECTION) COMTHROW(E_MGA_INVALID_ROLE); 00096 COMTHROW(ObjFor(f)->put_NamedRole(SrcName, srcrefs, src)); 00097 } 00098 COMTHROW(ObjFor(f)->put_NamedRole(DstName, dstrefs, dst)); 00099 *newobj = f.Detach(); 00100 } COMCATCH_IN_TRANSACTION(;) 00101 } 00102 00103 static CComPtr<IMgaFCOs> GetRefChain(IMgaFCO* fco) 00104 { 00105 CREATEEXCOLLECTION_FOR(MgaFCO, srcrefs); 00106 00107 CComQIPtr<IMgaReference> ref = fco; 00108 while (srcrefs && ref) 00109 { 00110 srcrefs->Add(ref); 00111 CComPtr<IMgaFCO> referred; 00112 COMTHROW(ref->get_Referred(&referred)); 00113 if (referred) 00114 { 00115 ref.Release(); 00116 ref = referred; 00117 } 00118 } 00119 return CComQIPtr<IMgaFCOs>(srcrefs); 00120 } 00121 00122 HRESULT FCO::CreateSimpleConnDisp( IMgaMetaRole *metar 00123 , IMgaFCO *srcobj, IMgaFCO *dstobj 00124 , IMgaFCO *srcref, IMgaFCO *dstref 00125 , IMgaFCO **newobj) 00126 { 00127 return CreateSimpleConn( metar, srcobj, dstobj, GetRefChain(srcref), GetRefChain(dstref), newobj); 00128 } 00129 00130 00131 /* ******************** CONNPOINT ********************************* */ 00132 00133 void CMgaConnPoint::GetConnPoint(FCO *f, CoreObj &c, IMgaConnPoint **cp) { 00134 ASSERT(GetMetaID(c) == DTID_CONNROLE); 00135 FCO::cphash::iterator ii; 00136 objid_type ll = c.GetObjID(); 00137 if((ii = f->connpointhash.find(ll)) != f->connpointhash.end()) { 00138 (*cp = (*ii).second)->AddRef(); 00139 } 00140 else { 00141 CComPtr<CMgaConnPoint> p; 00142 CreateComObject(p); 00143 #ifdef DEBUG 00144 p->MARKSIG('1'); 00145 #endif 00146 p->fco = f; 00147 p->cobj = c; 00148 f->connpointhash.insert(FCO::cphash::value_type(ll, p)); 00149 *cp = p.Detach(); 00150 } 00151 } 00152 00153 00154 CMgaConnPoint::~CMgaConnPoint() { 00155 MARKSIG('9'); 00156 // n.b. don't use GetObjId, it can COMTHROW when the project is closed 00157 objid_type t; 00158 HRESULT hr = cobj->get_ObjID(&t); 00159 if (SUCCEEDED(hr)) { 00160 FCO::cphash::iterator ii = fco->connpointhash.find(t); 00161 ASSERT(ii != fco->connpointhash.end()); 00162 fco->connpointhash.erase(ii); 00163 } 00164 } 00165 00166 00167 // the peers array is used in a tricky way here. 00168 // the first peercnt-2 members (if any) are references for connsegments 00169 // the peer before the last is the target 00170 // the last peer points back to the master object of the new connpoint 00171 // (it is protected by endreserve, and updated manually below) 00172 00173 bool AddConnPTask::Do(CoreObj self, std::vector<CoreObj> *peers) { 00174 CoreObj role; 00175 CMgaProject *mgaproject = ObjForCore(self)->mgaproject; 00176 if(maxinrole > 0) { 00177 long rolesofname = 0; 00178 ITERATE_THROUGH(self[ATTRID_CONNROLE+ATTRID_COLLECTION]) { 00179 if(rolename == CComBSTR(ITER[ATTRID_NAME])) rolesofname++; 00180 } 00181 if(rolesofname >= maxinrole) { 00182 if(!(*peers)[peercnt-1]) { // if this is the master connection 00183 COMTHROW(E_MGA_CONNROLE_USED); // indicate error 00184 } 00185 return false; // ... else silently ignore it 00186 } 00187 } 00188 COMTHROW(mgaproject->dataproject->CreateObject(DTID_CONNROLE,&role.ComPtr())); 00189 role[ATTRID_NAME] = rolename; 00190 role[ATTRID_CONNROLE] = self; 00191 role[ATTRID_XREF] = (*peers)[peercnt-2]; 00192 role[ATTRID_MASTEROBJ] = (*peers)[peercnt-1]; 00193 for(int i = 0; i < peercnt-2; i++) { 00194 CoreObj seg; 00195 COMTHROW(mgaproject->dataproject->CreateObject(DTID_CONNROLESEG,&seg.ComPtr())); 00196 seg[ATTRID_CONNSEG] = role; 00197 seg[ATTRID_SEGORDNUM] = i+1; 00198 seg[ATTRID_SEGREF] = (*peers)[i]; 00199 } 00200 00201 if( peercnt-2 >= 1) // additional check 00202 { 00203 CoreObj last_ref = (*peers)[peercnt - 3]; 00204 CoreObj tgt_model= last_ref[ATTRID_REFERENCE]; 00205 if (!last_ref.p) 00206 throw_com_error(E_MGA_INVALID_ARG, L"Cannot add refport to null reference"); 00207 CoreObj tgt_elem = (*peers)[peercnt - 2]; 00208 CoreObj parent = tgt_elem[ATTRID_FCOPARENT]; 00209 CoreObj bas_model= tgt_model[ATTRID_DERIVED]; // tgt_model must be a derived for GetDerivedEquivalent to succeed 00210 if( !COM_EQUAL(parent, tgt_model) && bas_model) { // JIRA:130? 00211 CoreObj new_tgt_elem; 00212 GetDerivedEquivalent( tgt_elem, tgt_model, new_tgt_elem); 00213 if( new_tgt_elem) // found tgt_elem's equivalent in tgt_model 00214 role[ATTRID_XREF] = new_tgt_elem; // overwrite the previous value: (*peers)[peercnt-2]; 00215 } 00216 } 00217 00218 IMgaObjectPtr iObject; 00219 ObjForCore(self)->getinterface(&iObject, 0); 00220 iObject->__Check(); 00221 ObjForCore((*peers)[0])->SelfMark(OBJEVENT_CONNECTED); 00222 ObjForCore(self)->SelfMark(OBJEVENT_RELATION); 00223 (*peers)[peercnt-1] = role; 00224 return true; 00225 } 00226 00227 HRESULT FCO::AddConnPoint(BSTR rolename, long maxinrole, IMgaFCO *target, IMgaFCOs *refs, IMgaConnPoint **pVal) { 00228 COMTRY_IN_TRANSACTION_MAYBE { 00229 CheckWrite(); 00230 long c = 0; 00231 if(refs) COMTHROW(refs->get_Count(&c)); 00232 std::vector<CoreObj> peers(c+2); 00233 CHECK_INSTRPAR(rolename); 00234 CHECK_MYINPTRPAR(target); 00235 CHECK_OUTPTRPAR(pVal); 00236 int pos = 0; 00237 if(refs) { 00238 CHECK_MYINPTRSPAR(refs); 00239 00240 MGACOLL_ITERATE(IMgaFCO, refs) { 00241 CoreObj l(MGACOLL_ITER); 00242 if(l.GetMetaID() != DTID_REFERENCE) COMTHROW(E_MGA_REFERENCE_EXPECTED); 00243 peers[pos++] = l; 00244 } MGACOLL_ITERATE_END; 00245 } 00246 peers[pos++] = CoreObj(target); 00247 peers[pos] = NULLCOREOBJ; 00248 AddConnPTask(maxinrole, rolename).DoWithDeriveds(self, &peers); 00249 CMgaConnPoint::GetConnPoint(this, peers[pos], pVal); 00250 } COMCATCH_IN_TRANSACTION_MAYBE(;); 00251 } 00252 00253 HRESULT FCO::get_ConnPoints(IMgaConnPoints **pVal) { 00254 CREATECOLLECTION_FOR(IMgaConnPoint, q); 00255 COMTRY { 00256 CoreObjs roles = self[ATTRID_CONNROLE + ATTRID_COLLECTION]; 00257 ITERATE_THROUGH(roles) { 00258 CComPtr<IMgaConnPoint> p; 00259 CMgaConnPoint::GetConnPoint(this, ITER, &p); 00260 q->Add(p); 00261 } 00262 *pVal = q.Detach(); 00263 } COMCATCH(;); 00264 } 00265 00266 00267 STDMETHODIMP CMgaConnPoint::get_Owner(IMgaConnection **pVal) { 00268 COMTRY { 00269 CHECK_OUTPTRPAR(pVal); 00270 ObjForCore(CoreObj(cobj[ATTRID_CONNROLE]))->getinterface(pVal); 00271 } COMCATCH(;); 00272 } 00273 00274 STDMETHODIMP CMgaConnPoint::get_ConnRole(BSTR *pVal) { 00275 COMTRY { 00276 CHECK_OUTSTRPAR(pVal); 00277 *pVal = CComBSTR(cobj[ATTRID_NAME]).Detach(); 00278 } COMCATCH(;); 00279 } 00280 00281 00282 00283 00284 class put_ConnRoleTask : public DeriveTreeTask { 00285 CComBSTR newrname; 00286 00287 bool Do(CoreObj self, std::vector<CoreObj> *peers = NULL) { 00288 self[ATTRID_NAME] = newrname; 00289 COMTHROW(ObjForCore(CoreObj(self[ATTRID_CONNROLE]))->Check()); 00290 return true; 00291 } 00292 00293 public: 00294 put_ConnRoleTask(BSTR nname) : newrname(nname) { ; } 00295 }; 00296 00297 00298 STDMETHODIMP CMgaConnPoint::put_ConnRole(BSTR newVal) { 00299 CMgaProject *mgaproject = fco->mgaproject; 00300 COMTRY_IN_TRANSACTION { 00301 CHECK_INSTRPAR(newVal); 00302 fco->CheckWrite(); 00303 //if(CComBSTR( cobj[ATTRID_NAME] ) = newVal) ... //zolmol: rewritten for VC7 00304 //if( (CComBSTR) cobj[ATTRID_NAME] = newVal) ... // also would be ok for vc7 00305 if( newVal) { // ... but this is more clear 00306 // FIXME: doesn't look good; we don't need a & ? 00307 (CComBSTR) cobj[ATTRID_NAME] = newVal; 00308 cobj[ATTRID_MASTEROBJ] = NULLCOREOBJ; 00309 put_ConnRoleTask(newVal).DoWithDeriveds(cobj); 00310 } 00311 } COMCATCH_IN_TRANSACTION(;); 00312 } 00313 00314 STDMETHODIMP CMgaConnPoint::get_Target(IMgaFCO **pVal) { 00315 COMTRY { 00316 CHECK_OUTPTRPAR(pVal); 00317 CoreObj t = cobj[ATTRID_XREF]; 00318 ASSERT(t); 00319 ObjForCore(t)->getinterface(pVal); 00320 } COMCATCH(;); 00321 } 00322 00323 STDMETHODIMP CMgaConnPoint::get_References(IMgaFCOs **pVal) { 00324 COMTRY { 00325 CHECK_OUTPTRPAR(pVal); 00326 CoreObjs refs = cobj[ATTRID_CONNSEG + ATTRID_COLLECTION]; 00327 refs.Sort(); 00328 CREATEEXCOLLECTION_FOR(MgaFCO, q); 00329 ITERATE_THROUGH(refs) { 00330 CComPtr<IMgaFCO> p; 00331 CoreObj t = ITER[ATTRID_SEGREF]; 00332 ASSERT(t); 00333 ObjForCore(t)->getinterface(&p); 00334 q->Add(p); 00335 } 00336 *pVal = q.Detach(); 00337 } COMCATCH(;); 00338 } 00339 00340 00341 void SingleObjTreeDelete(CoreObj &self, bool deleteself = true); 00342 00343 00344 void MgaConnPointDelete(CoreObj& cobj) 00345 { 00346 CoreObj fco = cobj[ATTRID_CONNROLE]; 00347 CoreObj target = cobj[ATTRID_XREF]; 00348 CoreObjs children = cobj[ATTRID_MASTEROBJ + ATTRID_COLLECTION]; 00349 ITERATE_THROUGH(children) 00350 { 00351 MgaConnPointDelete(ITER); 00352 } 00353 SingleObjTreeDelete(cobj); 00354 ObjForCore(fco)->SelfMark(OBJEVENT_RELATION); 00355 ObjForCore(target)->SelfMark(OBJEVENT_DISCONNECTED); 00356 } 00357 00358 STDMETHODIMP CMgaConnPoint::Remove() { 00359 CMgaProject *mgaproject = fco->mgaproject; 00360 COMTRY_IN_TRANSACTION { 00361 fco->CheckWrite(); 00362 00363 CoreObj fco = cobj[ATTRID_CONNROLE]; 00364 MgaConnPointDelete(cobj); 00365 COMTHROW(ObjForCore(fco)->Check()); 00366 } COMCATCH_IN_TRANSACTION(;); 00367 } 00368 00369 00370 // get conn points pointed at by this object 00371 HRESULT FCO::get_PartOfConns(IMgaConnPoints **pVal) { 00372 COMTRY { 00373 CheckRead(); 00374 CHECK_OUTPTRPAR(pVal); 00375 CoreObjs segs = self[ATTRID_XREF+ATTRID_COLLECTION]; 00376 CREATECOLLECTION_FOR(IMgaConnPoint, q); 00377 ITERATE_THROUGH(segs) { 00378 if(GetMetaID(ITER) != DTID_CONNROLE) continue; 00379 CoreObj conn = ITER[ATTRID_CONNROLE]; 00380 CComPtr<IMgaConnPoint> p; 00381 CMgaConnPoint::GetConnPoint(ObjForCore(conn), ITER, &p); 00382 q->Add(p); 00383 } 00384 *pVal = q.Detach(); 00385 } COMCATCH(;) 00386 } 00387 00388 00389 // get conn points running through this reference 00390 HRESULT FCO::get_UsedByConns(IMgaConnPoints **pVal) { 00391 COMTRY { 00392 CheckRead(); 00393 CHECK_OUTPTRPAR(pVal); 00394 CoreObjs segs = self[ATTRID_SEGREF+ATTRID_COLLECTION]; 00395 CREATECOLLECTION_FOR(IMgaConnPoint, q); 00396 ITERATE_THROUGH(segs) { 00397 CoreObj connrole = ITER[ATTRID_CONNSEG]; 00398 ASSERT(connrole); 00399 CoreObj conn = connrole[ATTRID_CONNROLE]; 00400 CComPtr<IMgaConnPoint> p; 00401 CMgaConnPoint::GetConnPoint(ObjForCore(conn), connrole, &p); 00402 q->Add(p); 00403 } 00404 *pVal = q.Detach(); 00405 } COMCATCH(;) 00406 } 00407 00408 HRESULT FCO::ConnCompareToBase(IMgaConnPoint *p, short *status) { 00409 COMTRY { 00410 CheckRead(); 00411 if(p) { 00412 CComPtr<IMgaConnection> z; 00413 COMTHROW(p->get_Owner(&z)); 00414 CHECK_MYINPTRPAR(z); 00415 } 00416 CHECK_OUTPAR(status); 00417 CoreObj base = self[ATTRID_DERIVED]; 00418 if(!base) COMTHROW(E_MGA_NOT_DERIVED); 00419 00420 if(p) { 00421 CoreObj l = static_cast<CMgaConnPoint *>(p)->cobj; 00422 *status = CoreObj(l[ATTRID_MASTEROBJ]) ? 0 : 1; 00423 } 00424 else { 00425 CoreObjs cpoints = self[ATTRID_CONNROLE + ATTRID_COLLECTION]; 00426 *status = 1; 00427 ITERATE_THROUGH(cpoints) { 00428 if(!CoreObj(ITER[ATTRID_MASTEROBJ])) break; 00429 } 00430 if(!ITER_BROKEN) *status = 0; 00431 } 00432 } COMCATCH(;); 00433 } 00434 00435 00436 HRESULT FCO::ConnRevertToBase(IMgaConnPoint *p) { 00437 COMTRY_IN_TRANSACTION { 00438 CheckWrite(); 00439 if(p) { 00440 CComPtr<IMgaConnection> z; 00441 COMTHROW(p->get_Owner(&z)); 00442 CHECK_MYINPTRPAR(z); 00443 } 00444 CoreObj base = self[ATTRID_DERIVED]; 00445 if(!base) COMTHROW(E_MGA_NOT_DERIVED); 00446 00447 if(p) { 00448 COMTHROW(E_MGA_NOT_IMPLEMENTED); 00449 } 00450 else { 00451 std::set<CoreObj> vv; 00452 { 00453 ITERATE_THROUGH(self[ATTRID_CONNROLE + ATTRID_COLLECTION]) { 00454 if (CoreObj(ITER[ATTRID_MASTEROBJ])) 00455 vv.insert(ITER[ATTRID_MASTEROBJ]); 00456 else 00457 MgaConnPointDelete(ITER); 00458 } 00459 } 00460 ITERATE_THROUGH(base[ATTRID_CONNROLE + ATTRID_COLLECTION]) { 00461 if(vv.find(ITER) == vv.end()) { 00462 coreobjpairhash crealist; 00463 CoreObj newcoreobj; 00464 ObjTreeDerive(mgaproject, ITER, newcoreobj, crealist, 0); // copy 00465 newcoreobj[ATTRID_CONNROLE] = self; 00466 int level; 00467 CoreObj rfco; 00468 GetRootOfDeriv(base, rfco, &level); 00469 ObjTreeReconnect(newcoreobj, crealist, self.FollowChain(ATTRID_FCOPARENT, level)); 00470 } 00471 } 00472 } 00473 } COMCATCH_IN_TRANSACTION(;); 00474 } 00475