GME  13
MgaCoreObj.cpp
Go to the documentation of this file.
00001 // 
00002 // CoreObj-based operations
00003 // 
00004 #include "stdafx.h"
00005 #include "MgaFCO.h"
00006 
00007 
00008 // Throws !!!!!
00009 metaid_type GetMetaID(const CoreObj &ob) {
00010                                 metaid_type t;
00011                                 CComPtr<ICoreMetaObject> mmo;
00012                                 COMTHROW(ob->get_MetaObject(&mmo));
00013                                 COMTHROW(mmo->get_MetaID(&t));
00014                                 return t;
00015 }
00016 
00017 
00018 
00019 CoreObj::CoreObj( IMgaObject *ptr) : CComPtr<ICoreObject>(ptr? ObjFor(ptr)->self:NULLCOREOBJ) {}
00020 
00021 void CoreObj::Create(ICoreObject *c, metaid_type mm) {
00022         CComPtr<ICoreProject> p;
00023         COMTHROW(c->get_Project(&p));
00024         Create(p,mm);
00025 }
00026 
00027 
00028 void CoreObj::Create(ICoreProject *p, metaid_type mm) {
00029         Release();
00030         COMTHROW(p->CreateObject(mm, &ComPtr()));
00031 }
00032 
00033 
00034 
00035 
00036 
00037 void GetRootFCO(CoreObj &fco,  /* out */ CoreObj &rootFCO, int *level) {
00038         CoreObj f = fco;
00039         int l = 0;
00040         ASSERT(f.IsFCO());
00041         while(f[ATTRID_ROLEMETA] != METAREF_NULL) {
00042                         f = f[ATTRID_FCOPARENT];
00043                         l++;
00044                         ASSERT(f.IsFCO());
00045         }
00046         rootFCO <<= f;
00047         if(level) *level = l;
00048 }
00049 
00050 void GetRootOfDeriv(CoreObj &fco,  /* out */ CoreObj &rootFCO, int *level) {
00051         CoreObj f = fco;
00052         CoreObj fret;
00053         int l = -1;
00054         ASSERT(f.IsFCO());
00055         while(CoreObjs(f[ATTRID_DERIVED+ATTRID_COLLECTION]).Count()) {
00056                         l++;
00057                         fret = f;
00058                         if(f.IsRootFCO()) break;
00059                         f = f[ATTRID_FCOPARENT];
00060                         ASSERT(f.IsFCO());
00061         }
00062         rootFCO <<= fret;
00063         if(level) *level = l;
00064 }
00065 
00066 
00067 bool IsContained(CoreObj &fco, CoreObj &parentFCO, int *level) {
00068         CoreObj f = fco;
00069         int l = 0;
00070         if(!f) return false;
00071         ASSERT(f.IsFCO());
00072         while(!COM_EQUAL(f, parentFCO)) {
00073                         if(f.IsRootFCO()) return false;
00074                         f = f[ATTRID_FCOPARENT];
00075                         ASSERT(f.IsFCO());
00076                         l++;
00077         }
00078         if(level) *level = l;
00079         return true;
00080 }
00081 
00082 
00083 bool IsFolderContained(CoreObj &fold, CoreObj &parentFold, int *level) {
00084         CoreObj f = fold;
00085         int l = 0;
00086         if( !f) return false;
00087         ASSERT( !f.IsFCO());
00088         while( !COM_EQUAL( f, parentFold)) {
00089                         if( f.IsRootFolder()) return false;
00090                         f = f[ ATTRID_FPARENT];
00091                         ASSERT( !f.IsFCO());
00092                         l++;
00093         }
00094         if(level) *level = l;
00095         return true;
00096 }
00097 
00098 
00099 CoreObj CoreObj::GetMaster(int offset) {
00100         CoreObj ret;
00101         metaid_type t = GetMetaID();
00102         if(t == DTID_CONNROLESEG) {     // the masters of connrolesegments is determined by ATTRID_SEGORDNUM matching:
00103                 CoreObj p = (*this)[ATTRID_CONNSEG];
00104                 CoreObj pm = p.GetMaster(offset);
00105                 if(pm) {
00106                         long ord = (*this)[ATTRID_SEGORDNUM];
00107                         CoreObjs ms = pm[ATTRID_CONNSEG + ATTRID_COLLECTION];
00108                         ITERATE_THROUGH(ms) {
00109                                 if(ord == ITER[ATTRID_SEGORDNUM]) { ret = ITER; break; }
00110                         }
00111                         ASSERT(("connrolesegment number mismatch in master role",ret));
00112                 }
00113         }
00114         else {
00115                 ret = (*this)[ATTRID_MASTEROBJ];
00116                 if(ret && offset > 1) ret = ret.GetMaster(offset - 1);
00117         }
00118         return ret;
00119 }
00120 
00121 
00122 CoreObj CoreObj::GetMgaObj() {
00123         CoreObj r = *this;
00124         while(true) {
00125                 metaid_type t = r.GetMetaID();
00126                 if(t >= DTID_MODEL && t <= DTID_FOLDER) break; 
00127                 attrid_type ai;
00128                 switch(t) {
00129                 case DTID_CONNROLE:             ai = ATTRID_CONNROLE;  break;
00130                 case DTID_CONNROLESEG:  ai = ATTRID_CONNSEG; break;
00131                 case DTID_SETNODE:              ai = ATTRID_SETMEMBER; break;
00132                 case DTID_CONSTRAINT:   ai = ATTRID_CONSTROWNER; break;
00133                 default:                                ai = ATTRID_ATTRPARENT;
00134                 }
00135                 r = r[ai];
00136                 if (!r) {
00137                         break;
00138                 }
00139         }
00140         return r;
00141 }
00142 
00143 
00144 CoreObj CoreObj::FollowChain(attrid_type id, int offset) {  // FOLLOWS a chain (like ATTRID_FCOPARENT) 
00145         CoreObj h = *this;                                                                          // returns NULL if list is shorter
00146         while(h && offset--) { h = h[id]; }
00147         return h;
00148 }
00149 
00150 void CoreObjs::Sort() { 
00151         CREATECOLLECTION_FOR(ICoreObject, q);
00152         long l = Count();
00153 //      for(long i = l; i > 0; i--) {
00154         for(long i = 1; i <= l; i++) {     // depends on what collection is used
00155                                                                           // (where data is plugged in on Add())
00156                 ITERATE_THROUGH((*this)) {
00157                         if(ITER[ATTRID_SEGORDNUM] == i) {
00158                                 q->Add(ITER);
00159                                 break;
00160                         }
00161                 }
00162                 if(!ITER_BROKEN) COMTHROW(E_MGA_DATA_INCONSISTENCY);
00163         }
00164         Attach(q.Detach());
00165 }
00166 
00167 bool CoreObj::IsRootOfDeriv() const {
00168         CoreObj parent = (*this)[ATTRID_FCOPARENT];
00169         return          (IsRootFCO() ||
00170                                 !CoreObjs(parent[ATTRID_DERIVED + ATTRID_COLLECTION]).Count()) && 
00171                                                 CoreObjs((*this)[ATTRID_DERIVED + ATTRID_COLLECTION]).Count();
00172 }
00173 
00174