GME  13
MetaParser.cpp
Go to the documentation of this file.
00001 
00002 #include "stdafx.h"
00003 #include "Parser.h"
00004 #include "MetaParser.h"
00005 #include <xercesc/util/PlatformUtils.hpp>
00006 #include <xercesc/parsers/SAXParser.hpp>
00007 
00008 #include <stdio.h>
00009 #include <fstream>//fstream.h
00010 // --------------------------- CMgaMetaParser
00011 
00012 CMgaMetaParser::CMgaMetaParser():currentPass(FIRST_PASS)
00013 {
00014 }
00015 
00016 CMgaMetaParser::~CMgaMetaParser()
00017 {
00018 }
00019 
00020 // ------- Methods
00021 
00022 STDMETHODIMP CMgaMetaParser::Parse(BSTR filename, BSTR connection)
00023 {
00024         try
00025         {
00026                 ASSERT( metaproject == NULL );
00027                 COMTHROW( metaproject.CoCreateInstance(L"Mga.MgaMetaProject") );
00028 
00029                 COMTHROW( metaproject->Create(connection) );
00030                 COMTHROW( metaproject->BeginTransaction() );
00031 
00032                 CopyTo(filename, xmlfile);
00033 
00034 
00035                 XMLPlatformUtilsTerminate_RAII term;
00036                 try
00037                 {
00038                         XMLPlatformUtils::Initialize();
00039 
00040                         foundconstraints = false;
00041                         explicitguid = false;
00042                         {
00043                                 SAXParser parser;
00044                                 //parser.setDoValidation(true);
00045                                 parser.setValidationScheme(SAXParser::Val_Always);
00046                                 parser.setDocumentHandler(this);
00047                                 parser.setErrorHandler(this);
00048                                 parser.setEntityResolver(this);
00049 
00050                                 
00051                                 //elementfuncs = elementfuncs_firstpass;
00052                                 currentPass = FIRST_PASS;
00053                                 parser.parse(xmlfile.c_str());
00054                         }
00055 
00056                         {
00057                                 SAXParser parser;
00058                                 parser.setValidationScheme(SAXParser::Val_Never);
00059                                 parser.setDocumentHandler(this);
00060                                 parser.setErrorHandler(this);
00061                                 parser.setEntityResolver(this);
00062 
00063                                 
00064                                 //elementfuncs = elementfuncs_secondpass;
00065                                 currentPass = SECOND_PASS;
00066                                 parser.parse(xmlfile.c_str());
00067                         }
00068                         if (!explicitguid) {
00069                                 // Old pradigm guid logic
00070 //calculate checksum:
00071                                 int sum = 0, cyc = 0;
00072                                 std::ifstream inf(xmlfile.c_str());
00073                                 while(inf.good()) {
00074                                         int l = inf.get();
00075                                         if(inf.eof()) break;
00076                                         sum += l << cyc;
00077                                         cyc = (cyc + 1) % 20;
00078                                 }
00079                                 sum += 1;    // compensate for meta bug in registering MetaID-s (January 2002)
00080 //
00081                                 OLECHAR buf[40];
00082                                 swprintf(buf, 40, L"{%08X-DEAD-BEEF-FEED-DAD00000000%c}",sum, foundconstraints?'1':'0');
00083                                 CComBstrObj bstr(buf);
00084                                 
00085                                 GUID guid;
00086                                 CopyTo(bstr, guid);
00087         
00088                                 CComVariant v;
00089                                 CopyTo(guid, v);
00090                                 
00091         
00092                                 COMTHROW( metaproject->put_GUID(v) );
00093                         }
00094                 }
00095             catch(const XMLException &e)
00096                 {
00097                         XmlStr desc(e.getMessage());
00098 
00099                         ThrowXmlError(L"%s", desc.c_str());
00100                 }
00101 
00102                 COMTHROW( metaproject->CommitTransaction() );
00103 
00104                 HRESULT hr = CloseAll();
00105                 if (FAILED(hr))
00106                         return hr; // IErrorInfo already set by metaproject->Close()
00107         }
00108         catch(hresult_exception &e)
00109         {
00110                 if( metaproject != NULL )
00111                         metaproject->AbortTransaction();
00112 
00113                 CloseAll();
00114 
00115                 ASSERT( FAILED(e.hr) );
00116                 if( e.hr == E_XMLPARSER )
00117                         SetErrorInfo(errorinfo);
00118                 else
00119                         SetErrorInfo2(e.hr);
00120 
00121                 return e.hr;
00122         }
00123         return S_OK;
00124 }
00125 
00126 HRESULT CMgaMetaParser::CloseAll()
00127 {
00128         HRESULT hr;
00129 
00130         elements.clear();
00131 
00132         if (metaproject != NULL)
00133                 hr = metaproject->Close();
00134         else
00135                 hr = S_OK;
00136 
00137         metaproject = NULL;
00138         return hr;
00139 };
00140 
00141 // ------- Attributes
00142 
00143 const std::tstring CMgaMetaParser::GetNextToken(std::tstring::const_iterator &i,
00144         std::tstring::const_iterator &e, std::tstring::const_iterator end)
00145 {
00146         i = e;
00147         while( i != end && *i == ' ' )
00148                 ++i;
00149 
00150         e = i;
00151         while( e != end && *e != ' ' )
00152                 ++e;
00153 
00154         return std::tstring(i, e);
00155 }
00156 
00157 
00158 void CMgaMetaParser::fireStartFunction(const std::tstring & namestr, const attributes_type& attributes)
00159 {
00160         if(currentPass == FIRST_PASS)
00161         {
00162                 for(unsigned int index = 0; !elementfuncs_firstpass[index].name.empty(); index++)
00163                 {
00164                                 if( namestr == elementfuncs_firstpass[index].name )
00165                                 {
00166                                         elementfuncs_firstpass[index].Start(this, attributes);
00167                                         break;
00168                                 }
00169                 }
00170         }
00171         else
00172         {
00173                 for(unsigned int index = 0; !elementfuncs_secondpass[index].name.empty(); index++)
00174                 {
00175                                 if( namestr == elementfuncs_secondpass[index].name )
00176                                 {
00177                                         elementfuncs_secondpass[index].Start(this, attributes);
00178                                         break;
00179                                 }
00180                 }
00181 
00182         }
00183 }
00184 
00185 
00186 void CMgaMetaParser::fireEndFunction(const std::tstring & namestr)
00187 {
00188         if(currentPass == FIRST_PASS)
00189         {
00190                 for(unsigned int index = 0; !elementfuncs_firstpass[index].name.empty(); index++)
00191                 {
00192                                 if( namestr == elementfuncs_firstpass[index].name )
00193                                 {
00194                                         elementfuncs_firstpass[index].End(this);
00195                                         break;
00196                                 }
00197                 }
00198         }
00199         else
00200         {
00201                 for(unsigned int index = 0; !elementfuncs_secondpass[index].name.empty(); index++)
00202                 {
00203                                 if( namestr == elementfuncs_secondpass[index].name )
00204                                 {
00205                                         elementfuncs_secondpass[index].End(this);
00206                                         break;
00207                                 }
00208                 }
00209 
00210         }
00211 }
00212 
00213 
00214 // ------- ElementFuncs
00215 
00216 CMgaMetaParser::elementfunc CMgaMetaParser::elementfuncs_firstpass[] = 
00217 {
00218         elementfunc(_T("paradigm"), StartParadigm, EndNone),
00219         elementfunc(_T("comment"), StartNone, EndComment),
00220         elementfunc(_T("author"), StartNone, EndAuthor),
00221         elementfunc(_T("dispname"), StartNone, EndDispName),
00222         elementfunc(_T("folder"), StartFolder, EndNone),
00223         elementfunc(_T("atom"), StartAtom, EndNone),
00224         elementfunc(_T("model"), StartModel, EndNone),
00225         elementfunc(_T("connection"), StartConnection, EndNone),
00226         elementfunc(_T("reference"), StartReference, EndNone),
00227         elementfunc(_T("set"), StartSet, EndNone),
00228         elementfunc(_T("attrdef"), StartAttrDef, EndNone),
00229         elementfunc(_T("regnode"), StartRegNode, EndNone),
00230         elementfunc(_T("connjoint"), StartConnJoint, EndNone),
00231         elementfunc(_T("pointerspec"), StartPointerSpec, EndNone),
00232         elementfunc(_T("pointeritem"), StartPointerItem, EndNone),
00233         elementfunc(_T("enumitem"), StartEnumItem, EndNone),
00234         elementfunc(_T("constraint"), StartConstraint, EndConstraint),
00235         elementfunc(_T(""), NULL, NULL)
00236 };
00237 
00238 CMgaMetaParser::elementfunc CMgaMetaParser::elementfuncs_secondpass[] = 
00239 {
00240         elementfunc(_T("folder"), StartFolder2, EndNone),
00241         elementfunc(_T("model"), StartFCO2, EndNone),
00242         elementfunc(_T("atom"), StartFCO2, EndNone),
00243         elementfunc(_T("connection"), StartFCO2, EndNone),
00244         elementfunc(_T("reference"), StartFCO2, EndNone),
00245         elementfunc(_T("set"), StartFCO2, EndNone),
00246         elementfunc(_T("role"), StartRole2, EndNone),
00247         elementfunc(_T("aspect"), StartAspect2, EndNone),
00248         elementfunc(_T("part"), StartPart2, EndNone),
00249         elementfunc(_T("regnode"), StartRegNode, EndNone),
00250         elementfunc(_T("dispname"), StartNone, EndDispName),
00251         elementfunc(_T(""), NULL, NULL)
00252 };
00253 
00254 // ------- Element Handlers
00255 
00256 void CMgaMetaParser::StartParadigm(const attributes_type &attributes)
00257 {
00258         GetCurrent().object = metaproject;
00259 
00260         attributes_iterator i = attributes.begin();
00261         attributes_iterator e = attributes.end();
00262         while( i != e )
00263         {
00264                 Attr(i, _T("name"), metaproject, &IMgaMetaProject::put_Name);
00265                 Attr(i, _T("version"), metaproject, &IMgaMetaProject::put_Version);
00266                 
00267                 /*  New Paradigm GUID logic */  
00268                 if( i->first == _T("guid") )
00269                 {
00270                         _bstr_t bstr = i->second.c_str();
00271 
00272                         GUID guid;
00273                         CopyTo(bstr, guid);
00274 
00275                         CComVariant v;
00276                         CopyTo(guid, v);
00277 
00278                         COMTHROW( metaproject->put_GUID(v) );
00279                         explicitguid = true;
00280                 }
00281 
00282                 Attr(i, _T("cdate"), metaproject, &IMgaMetaProject::put_CreatedAt);
00283                 Attr(i, _T("mdate"), metaproject, &IMgaMetaProject::put_ModifiedAt);
00284 
00285                 ++i;
00286         }
00287 }
00288 
00289 void CMgaMetaParser::EndComment()
00290 {
00291         if( GetPrevName() == _T("paradigm") )
00292         {
00293                 COMTHROW( metaproject->put_Comment(PutInBstr(GetCurrData())) );
00294         }
00295         else
00296                 HR_THROW(E_INVALID_DTD);
00297 }
00298 
00299 void CMgaMetaParser::EndAuthor()
00300 {
00301         if( GetPrevName() == _T("paradigm") )
00302         {
00303                 COMTHROW( metaproject->put_Author(PutInBstr(GetCurrData())) );
00304         }
00305         else
00306                 HR_THROW(E_INVALID_DTD);
00307 }
00308 
00309 void CMgaMetaParser::EndDispName()
00310 {
00311         if( GetPrevious().object == NULL )
00312                 return;
00313 
00314         if( GetPrevName() == _T("paradigm") )
00315         {
00316                 COMTHROW( metaproject->put_DisplayedName(PutInBstr(GetCurrData())) );
00317         }
00318         else if( GetPrevName() == _T("constraint") )
00319         {
00320                 CComObjPtr<IMgaMetaConstraint> c;
00321                 GetPrevObj(c);
00322                 COMTHROW( c->put_DisplayedName(PutInBstr(GetCurrData())) );
00323         }
00324         else if( GetPrevious().object != NULL ) 
00325         {
00326                 CComObjPtr<IMgaMetaBase> prev;
00327                 GetPrevObj(prev);
00328                 COMTHROW( prev->put_DisplayedName(PutInBstr(GetCurrData())) );
00329         }
00330 }
00331 
00332 void CMgaMetaParser::StartFolder(const attributes_type &attributes)
00333 {
00334         CComObjPtr<IMgaMetaFolder> folder;
00335 
00336         if( GetPrevName() == _T("paradigm") )
00337         {
00338                 COMTHROW( metaproject->get_RootFolder(PutOut(folder)) );
00339         }
00340         else
00341         {
00342                 CComObjPtr<IMgaMetaFolder> prev;
00343                 GetPrevObj(prev);
00344                 COMTHROW( prev->DefineFolder(PutOut(folder)) );
00345         }
00346 
00347         ASSERT( folder != NULL );
00348         GetCurrent().object = folder;
00349 
00350         attributes_iterator i = attributes.begin();
00351         attributes_iterator e = attributes.end();
00352         while( i != e )
00353         {
00354                 Attr(i, _T("name"), folder, &IMgaMetaFolder::put_Name);
00355                 Attr(i, _T("metaref"), folder, &IMgaMetaFolder::put_MetaRef);
00356 
00357                 ++i;
00358         }
00359 }
00360 
00361 void CMgaMetaParser::StartFolder2(const attributes_type &attributes)
00362 {
00363         ASSERT( GetCurrent().object == NULL );
00364 
00365         CComObjPtr<IMgaMetaFolder> folder;
00366 
00367         if( GetPrevName() == _T("paradigm") )
00368         {
00369                 ASSERT( metaproject != NULL );
00370                 COMTHROW( metaproject->get_RootFolder(PutOut(folder)) );
00371         }
00372         else
00373         {
00374                 CComObjPtr<IMgaMetaFolder> prev;
00375                 GetPrevObj(prev);
00376 
00377                 HRESULT hr = prev->get_DefinedFolderByName(PutInBstr(GetByName(attributes, _T("name"))),
00378                         VARIANT_FALSE, PutOut(folder));
00379 
00380                 if( hr == E_NOTFOUND )
00381                         ThrowXmlError(_T("Parent folder %s was not found"), GetByName(attributes, _T("name")).c_str());
00382                 else
00383                         COMTHROW(hr);
00384         }
00385 
00386         ASSERT( folder != NULL );
00387         GetCurrent().object = folder;
00388 
00389         attributes_iterator i = attributes.begin();
00390         attributes_iterator e = attributes.end();
00391         while( i != e )
00392         {
00393                 if( i->first == _T("subfolders") )
00394                 {
00395                         std::tstring::const_iterator ip = i->second.begin();
00396                         std::tstring::const_iterator ep = ip;
00397                         std::tstring::const_iterator xp = i->second.end();
00398                         for(;;)
00399                         {
00400                                 std::tstring token = GetNextToken(ip, ep, xp);
00401                                 if( ip == xp )
00402                                         break;
00403 
00404                                 ASSERT( !token.empty() );
00405 
00406                                 CComObjPtr<IMgaMetaFolder> child;
00407                                 HRESULT hr = folder->get_DefinedFolderByName(PutInBstr(token),
00408                                         VARIANT_TRUE, PutOut(child));
00409 
00410                                 if( hr == E_NOTFOUND )
00411                                         ThrowXmlError(_T("Defined folder %s was not found"), token.c_str());
00412                                 else
00413                                         COMTHROW(hr);
00414 
00415                                 COMTHROW( folder->AddLegalChildFolder(child) );
00416                         }
00417                 }
00418                 else if( i->first == _T("rootobjects") )
00419                 {
00420                         std::tstring::const_iterator ip = i->second.begin();
00421                         std::tstring::const_iterator ep = ip;
00422                         std::tstring::const_iterator xp = i->second.end();
00423                         for(;;)
00424                         {
00425                                 std::tstring token = GetNextToken(ip, ep, xp);
00426                                 if( ip == xp )
00427                                         break;
00428 
00429                                 ASSERT( !token.empty() );
00430 
00431                                 CComObjPtr<IMgaMetaFCO> fco;
00432                                 HRESULT hr = folder->get_DefinedFCOByName(PutInBstr(token),
00433                                         VARIANT_TRUE, PutOut(fco));
00434 
00435                                 if( hr == E_NOTFOUND )
00436                               ThrowXmlError(_T("No definition for FCO %s was not found"), token.c_str());
00437                                 else
00438                                         COMTHROW(hr);
00439 
00440                                 COMTHROW( folder->AddLegalRootObject(fco) );
00441                         }
00442                 }
00443 
00444                 ++i;
00445         }
00446 
00447 }
00448 
00449 void CMgaMetaParser::StartAtom(const attributes_type &attributes)
00450 {
00451         CComObjPtr<IMgaMetaAtom> atom;
00452 
00453         if( GetPrevName() == _T("folder") )
00454         {
00455                 CComObjPtr<IMgaMetaFolder> prev;
00456                 GetPrevObj(prev);
00457                 COMTHROW( prev->DefineAtom(PutOut(atom)) );
00458         }
00459         else
00460         {
00461                 CComObjPtr<IMgaMetaModel> prev;
00462                 GetPrevObj(prev);
00463                 COMTHROW( prev->DefineAtom(PutOut(atom)) );
00464         }
00465 
00466         ASSERT( atom != NULL );
00467         GetCurrent().object = atom;
00468 
00469         attributes_iterator i = attributes.begin();
00470         attributes_iterator e = attributes.end();
00471         while( i != e )
00472         {
00473                 Attr(i, _T("name"), atom, &IMgaMetaAtom::put_Name);
00474                 Attr(i, _T("metaref"), atom, &IMgaMetaAtom::put_MetaRef);
00475                 ++i;
00476         }
00477         COMTHROW(atom->put_AliasingEnabled((GetByName(attributes, _T("aliasenabled")) == _T("yes") ) ? VARIANT_TRUE : VARIANT_FALSE));
00478 }
00479 
00480 void CMgaMetaParser::StartConnection(const attributes_type &attributes)
00481 {
00482         CComObjPtr<IMgaMetaConnection> conn;
00483 
00484         if( GetPrevName() == _T("folder") )
00485         {
00486                 CComObjPtr<IMgaMetaFolder> prev;
00487                 GetPrevObj(prev);
00488                 COMTHROW( prev->DefineConnection(PutOut(conn)) );
00489         }
00490         else
00491         {
00492                 CComObjPtr<IMgaMetaModel> prev;
00493                 GetPrevObj(prev);
00494                 COMTHROW( prev->DefineConnection(PutOut(conn)) );
00495         }
00496 
00497         ASSERT( conn != NULL );
00498         GetCurrent().object = conn;
00499 
00500         attributes_iterator i = attributes.begin();
00501         attributes_iterator e = attributes.end();
00502         while( i != e )
00503         {
00504                 Attr(i, _T("name"), conn, &IMgaMetaConnection::put_Name);
00505                 Attr(i, _T("metaref"), conn, &IMgaMetaConnection::put_MetaRef);
00506                 ++i;
00507         }
00508         COMTHROW(conn->put_AliasingEnabled((GetByName(attributes, _T("aliasenabled")) == _T("yes") ) ? VARIANT_TRUE : VARIANT_FALSE));
00509 }
00510 
00511 void CMgaMetaParser::StartConnJoint(const attributes_type &attributes)
00512 {
00513         CComObjPtr<IMgaMetaConnJoint> joint;
00514 
00515         CComObjPtr<IMgaMetaConnection> prev;
00516         GetPrevObj(prev);
00517         COMTHROW( prev->CreateJoint(PutOut(joint)) );
00518 
00519         ASSERT( joint != NULL );
00520         GetCurrent().object = joint;
00521 }
00522 
00523 void CMgaMetaParser::StartPointerSpec(const attributes_type &attributes)
00524 {
00525         CComObjPtr<IMgaMetaPointerSpec> spec;
00526 
00527         if( GetPrevName() == _T("connjoint") )
00528         {
00529                 CComObjPtr<IMgaMetaConnJoint> prev;
00530                 GetPrevObj(prev);
00531                 COMTHROW( prev->CreatePointerSpec(PutOut(spec)) );
00532         }
00533         else if( GetPrevName() == _T("reference") )
00534         {
00535                 CComObjPtr<IMgaMetaReference> prev;
00536                 GetPrevObj(prev);
00537                 COMTHROW( prev->get_RefSpec(PutOut(spec)) );
00538         }
00539         else
00540         {
00541                 ASSERT( GetPrevName() == _T("set") );
00542 
00543                 CComObjPtr<IMgaMetaSet> prev;
00544                 GetPrevObj(prev);
00545                 COMTHROW( prev->get_MemberSpec(PutOut(spec)) );
00546         }
00547 
00548         ASSERT( spec != NULL );
00549         GetCurrent().object = spec;
00550 
00551         attributes_iterator i = attributes.begin();
00552         attributes_iterator e = attributes.end();
00553         while( i != e )
00554         {
00555                 if( i->first == _T("name") )
00556                         COMTHROW( spec->put_Name(PutInBstr(i->second.c_str())) );
00557 
00558                 ++i;
00559         }
00560 }
00561 
00562 void CMgaMetaParser::StartPointerItem(const attributes_type &attributes)
00563 {
00564         CComObjPtr<IMgaMetaPointerItem> item;
00565 
00566         CComObjPtr<IMgaMetaPointerSpec> prev;
00567         GetPrevObj(prev);
00568         COMTHROW( prev->CreateItem(PutOut(item)) );
00569 
00570         attributes_iterator i = attributes.begin();
00571         attributes_iterator e = attributes.end();
00572         while( i != e )
00573         {
00574                 Attr(i, _T("desc"), item, &IMgaMetaPointerItem::put_Desc);
00575 
00576                 ++i;
00577         }
00578 }
00579 
00580 void CMgaMetaParser::StartReference(const attributes_type &attributes)
00581 {
00582         CComObjPtr<IMgaMetaReference> reference;
00583 
00584         if( GetPrevName() == _T("folder") )
00585         {
00586                 CComObjPtr<IMgaMetaFolder> prev;
00587                 GetPrevObj(prev);
00588                 COMTHROW( prev->DefineReference(PutOut(reference)) );
00589         }
00590         else
00591         {
00592                 CComObjPtr<IMgaMetaModel> prev;
00593                 GetPrevObj(prev);
00594                 COMTHROW( prev->DefineReference(PutOut(reference)) );
00595         }
00596 
00597         ASSERT( reference != NULL );
00598         GetCurrent().object = reference;
00599 
00600         attributes_iterator i = attributes.begin();
00601         attributes_iterator e = attributes.end();
00602         while( i != e )
00603         {
00604                 Attr(i, _T("name"), reference, &IMgaMetaReference::put_Name);
00605                 Attr(i, _T("metaref"), reference, &IMgaMetaReference::put_MetaRef);
00606                 ++i;
00607         }
00608         COMTHROW(reference->put_AliasingEnabled((GetByName(attributes, _T("aliasenabled")) == _T("yes") ) ? VARIANT_TRUE : VARIANT_FALSE));
00609 }
00610 
00611 void CMgaMetaParser::StartSet(const attributes_type &attributes)
00612 {
00613         CComObjPtr<IMgaMetaSet> set;
00614 
00615         if( GetPrevName() == _T("folder") )
00616         {
00617                 CComObjPtr<IMgaMetaFolder> prev;
00618                 GetPrevObj(prev);
00619                 COMTHROW( prev->DefineSet(PutOut(set)) );
00620         }
00621         else
00622         {
00623                 CComObjPtr<IMgaMetaModel> prev;
00624                 GetPrevObj(prev);
00625                 COMTHROW( prev->DefineSet(PutOut(set)) );
00626         }
00627 
00628         ASSERT( set != NULL );
00629         GetCurrent().object = set;
00630 
00631         attributes_iterator i = attributes.begin();
00632         attributes_iterator e = attributes.end();
00633         while( i != e )
00634         {
00635                 Attr(i, _T("name"), set, &IMgaMetaSet::put_Name);
00636                 Attr(i, _T("metaref"), set, &IMgaMetaSet::put_MetaRef);
00637 
00638                 ++i;
00639         }
00640         COMTHROW(set->put_AliasingEnabled((GetByName(attributes, _T("aliasenabled")) == _T("yes") ) ? VARIANT_TRUE : VARIANT_FALSE));
00641 }
00642 
00643 void CMgaMetaParser::StartModel(const attributes_type &attributes)
00644 {
00645         CComObjPtr<IMgaMetaModel> model;
00646 
00647         if( GetPrevName() == _T("folder") )
00648         {
00649                 CComObjPtr<IMgaMetaFolder> prev;
00650                 GetPrevObj(prev);
00651                 COMTHROW( prev->DefineModel(PutOut(model)) );
00652         }
00653         else
00654         {
00655                 CComObjPtr<IMgaMetaModel> prev;
00656                 GetPrevObj(prev);
00657                 COMTHROW( prev->DefineModel(PutOut(model)) );
00658         }
00659 
00660         ASSERT( model != NULL );
00661         GetCurrent().object = model;
00662 
00663         attributes_iterator i = attributes.begin();
00664         attributes_iterator e = attributes.end();
00665         while( i != e )
00666         {
00667                 Attr(i, _T("name"), model, &IMgaMetaModel::put_Name);
00668                 Attr(i, _T("metaref"), model, &IMgaMetaModel::put_MetaRef);
00669 
00670                 ++i;
00671         }
00672         COMTHROW(model->put_AliasingEnabled((GetByName(attributes, _T("aliasenabled")) == _T("yes") ) ? VARIANT_TRUE : VARIANT_FALSE));
00673 }
00674 
00675 void CMgaMetaParser::StartFCO2(const attributes_type &attributes)
00676 {
00677         ASSERT( GetCurrent().object == NULL );
00678 
00679         CComObjPtr<IMgaMetaFCO> fco;
00680         HRESULT hr;
00681 
00682         if( GetPrevName() == _T("folder") )
00683         {
00684                 CComObjPtr<IMgaMetaFolder> prev;
00685                 GetPrevObj(prev);
00686                 hr = prev->get_DefinedFCOByName(PutInBstr(GetByName(attributes, _T("name"))),
00687                         VARIANT_FALSE, PutOut(fco));
00688         }
00689         else
00690         {
00691                 CComObjPtr<IMgaMetaModel> prev;
00692                 GetPrevObj(prev);
00693                 hr = prev->get_DefinedFCOByName(PutInBstr(GetByName(attributes, _T("name"))),
00694                         VARIANT_FALSE, PutOut(fco));
00695         }
00696 
00697         if( hr == E_NOTFOUND )
00698                 ThrowXmlError(_T("Parent FCO %s was not found"), GetByName(attributes, _T("name")).c_str());
00699         else
00700                 COMTHROW(hr);
00701 
00702         ASSERT( fco != NULL );
00703         GetCurrent().object = fco;
00704 
00705         attributes_iterator i = attributes.begin();
00706         attributes_iterator e = attributes.end();
00707         while( i != e )
00708         {
00709                 if( i->first == _T("attributes") )
00710                 {
00711                         std::tstring::const_iterator ip = i->second.begin();
00712                         std::tstring::const_iterator ep = ip;
00713                         std::tstring::const_iterator xp = i->second.end();
00714                         for(;;)
00715                         {
00716                                 std::tstring token = GetNextToken(ip, ep, xp);
00717                                 if( ip == xp )
00718                                         break;
00719 
00720                                 ASSERT( !token.empty() );
00721 
00722                                 CComObjPtr<IMgaMetaAttribute> attr;
00723                                 HRESULT hr = fco->get_DefinedAttributeByName(PutInBstr(token),
00724                                         VARIANT_TRUE, PutOut(attr));
00725 
00726                                 if( hr == E_NOTFOUND )
00727                                         ThrowXmlError(_T("Defined attribute %s was not found"), token.c_str());
00728                                 else
00729                                         COMTHROW(hr);
00730 
00731                                 COMTHROW( fco->AddAttribute(attr) );
00732                         }
00733                 }
00734 
00735                 ++i;
00736         }
00737 }
00738 
00739 void CMgaMetaParser::StartAttrDef(const attributes_type &attributes)
00740 {
00741         CComObjPtr<IMgaMetaAttribute> attr;
00742 
00743         if( GetPrevName() == _T("folder") )
00744         {
00745                 CComObjPtr<IMgaMetaFolder> prev;
00746                 GetPrevObj(prev);
00747                 COMTHROW( prev->DefineAttribute(PutOut(attr)) );
00748         }
00749         else
00750         {
00751                 CComObjPtr<IMgaMetaFCO> prev;
00752                 GetPrevObj(prev);
00753                 COMTHROW( prev->DefineAttribute(PutOut(attr)) );
00754         }
00755 
00756         ASSERT( attr != NULL );
00757         GetCurrent().object = attr;
00758         
00759         attr->put_Viewable( VARIANT_TRUE); // default behaviour if no 'viewable' attribute is found
00760 
00761         attributes_iterator i = attributes.begin();
00762         attributes_iterator e = attributes.end();
00763         while( i != e )
00764         {
00765                 Attr(i, _T("name"), attr, &IMgaMetaAttribute::put_Name);
00766                 Attr(i, _T("defvalue"), attr, &IMgaMetaAttribute::put_DefaultValue);
00767                 Attr(i, _T("metaref"), attr, &IMgaMetaAttribute::put_MetaRef);
00768 
00769                 if( i->first == _T("valuetype") )
00770                 {
00771                         attval_enum attval;
00772 
00773                         if( i->second == _T("integer") )
00774                                 attval = ATTVAL_INTEGER;
00775                         else if( i->second == _T("double") )
00776                                 attval = ATTVAL_DOUBLE;
00777                         else if( i->second == _T("boolean") )
00778                                 attval = ATTVAL_BOOLEAN;
00779                         else if( i->second == _T("string") )
00780                                 attval = ATTVAL_STRING;
00781                         else if( i->second == _T("enum") )
00782                                 attval = ATTVAL_ENUM;
00783                         else if( i->second == _T("dynamic") )
00784                                 attval = ATTVAL_DYNAMIC;
00785                         else
00786                                 HR_THROW(E_XMLPARSER);
00787 
00788                         COMTHROW( attr->put_ValueType(attval) );
00789                 }
00790 
00791                 if( i->first == _T("viewable") && i->second == _T("no"))
00792                         attr->put_Viewable( VARIANT_FALSE);
00793 
00794                 ++i;
00795         }
00796 }
00797 
00798 void CMgaMetaParser::StartEnumItem(const attributes_type &attributes)
00799 {
00800         CComObjPtr<IMgaMetaEnumItem> item;
00801 
00802         CComObjPtr<IMgaMetaAttribute> prev;
00803         GetPrevObj(prev);
00804         COMTHROW( prev->CreateEnumItem(PutOut(item)) );
00805 
00806         attributes_iterator i = attributes.begin();
00807         attributes_iterator e = attributes.end();
00808         while( i != e )
00809         {
00810                 Attr(i, _T("dispname"), item, &IMgaMetaEnumItem::put_DisplayedName);
00811                 Attr(i, _T("value"), item, &IMgaMetaEnumItem::put_Value);
00812 
00813                 ++i;
00814         }
00815 }
00816 
00817 void CMgaMetaParser::StartRole2(const attributes_type &attributes)
00818 {
00819         CComObjPtr<IMgaMetaModel> prev;
00820         GetPrevObj(prev);
00821 
00822         CComObjPtr<IMgaMetaFCO> fco;
00823         HRESULT hr = prev->get_DefinedFCOByName(PutInBstr(GetByName(attributes, _T("kind"))),
00824                 VARIANT_TRUE, PutOut(fco));
00825 
00826         if( hr == E_NOTFOUND )
00827                 ThrowXmlError(_T("Kind FCO %s was not found"), GetByName(attributes, _T("kind")).c_str());
00828         else
00829                 COMTHROW(hr);
00830 
00831         ASSERT( fco != NULL );
00832 
00833         CComObjPtr<IMgaMetaRole> role;
00834         COMTHROW( prev->CreateRole(fco, PutOut(role)) );
00835 
00836         ASSERT( role != NULL );
00837         GetCurrent().object = role;
00838 
00839         attributes_iterator i = attributes.begin();
00840         attributes_iterator e = attributes.end();
00841         while( i != e )
00842         {
00843                 Attr(i, _T("name"), role, &IMgaMetaRole::put_Name);
00844                 Attr(i, _T("metaref"), role, &IMgaMetaRole::put_MetaRef);
00845 
00846                 ++i;
00847         }
00848 }
00849 
00850 void CMgaMetaParser::StartAspect2(const attributes_type &attributes)
00851 {
00852         CComObjPtr<IMgaMetaAspect> aspect;
00853 
00854         CComObjPtr<IMgaMetaModel> prev;
00855         GetPrevObj(prev);
00856         COMTHROW( prev->CreateAspect(PutOut(aspect)) );
00857 
00858         CComObjPtr<IMgaMetaModel> model;
00859         COMTHROW( prev.QueryInterface(model) );
00860 
00861         ASSERT( aspect != NULL );
00862         GetCurrent().object = aspect;
00863 
00864         attributes_iterator i = attributes.begin();
00865         attributes_iterator e = attributes.end();
00866         while( i != e )
00867         {
00868                 Attr(i, _T("name"), aspect, &IMgaMetaAspect::put_Name);
00869                 Attr(i, _T("metaref"), aspect, &IMgaMetaAspect::put_MetaRef);
00870 
00871                 if( i->first == _T("attributes") )
00872                 {
00873                         std::tstring::const_iterator ip = i->second.begin();
00874                         std::tstring::const_iterator ep = ip;
00875                         std::tstring::const_iterator xp = i->second.end();
00876                         for(;;)
00877                         {
00878                                 std::tstring token = GetNextToken(ip, ep, xp);
00879                                 if( ip == xp )
00880                                         break;
00881 
00882                                 ASSERT( !token.empty() );
00883 
00884                                 CComObjPtr<IMgaMetaAttribute> attr;
00885                                 HRESULT hr = model->get_AttributeByName(PutInBstr(token), PutOut(attr));
00886 
00887                                 if( hr == E_NOTFOUND )
00888                                         ThrowXmlError(_T("Attribute %s was not found"), token.c_str());
00889                                 else
00890                                         COMTHROW(hr);
00891 
00892                                 COMTHROW( aspect->AddAttribute(attr) );
00893                         }
00894                 }
00895         
00896                 ++i;
00897         }
00898 }
00899 
00900 void CMgaMetaParser::StartPart2(const attributes_type &attributes)
00901 {
00902         CComObjPtr<IMgaMetaPart> part;
00903 
00904         CComObjPtr<IMgaMetaAspect> prev;
00905         GetPrevObj(prev);
00906 
00907         ASSERT( elements.size() >= 3 );
00908         ASSERT( elements[elements.size()-3].name == _T("model") );
00909 
00910         CComObjPtr<IMgaMetaModel> model;
00911         COMTHROW( elements[elements.size()-3].object.QueryInterface(model) );
00912         ASSERT( model != NULL );
00913 
00914         CComObjPtr<IMgaMetaRole> role;
00915         HRESULT hr = model->get_RoleByName(PutInBstr(GetByName(attributes, _T("role"))), PutOut(role));
00916 
00917         if( hr == E_NOTFOUND )
00918                 ThrowXmlError(_T("Role %s was not found"), GetByName(attributes, _T("role")).c_str());
00919         else
00920                 COMTHROW(hr);
00921 
00922         ASSERT( role != NULL );
00923 
00924         COMTHROW( prev->CreatePart(role, PutOut(part)) );
00925         ASSERT( part != NULL );
00926 
00927         attributes_iterator i = attributes.begin();
00928         attributes_iterator e = attributes.end();
00929         while( i != e )
00930         {
00931                 Attr(i, _T("kindaspect"), part, &IMgaMetaPart::put_KindAspect);
00932                 Attr(i, _T("metaref"), part, &IMgaMetaPart::put_MetaRef);
00933 
00934                 if( i->first == _T("primary") )
00935                 {
00936                         COMTHROW( part->put_IsPrimary(i->second == _T("yes") ? VARIANT_TRUE : VARIANT_FALSE) );
00937                 }
00938                 else if( i->first == _T("linked") )
00939                 {
00940                         COMTHROW( part->put_IsLinked(i->second == _T("yes") ? VARIANT_TRUE : VARIANT_FALSE) );
00941                 }
00942 
00943                 ++i;
00944         }
00945 
00946 }
00947 
00948 void CMgaMetaParser::StartRegNode(const attributes_type &attributes)
00949 {
00950         if( GetPrevious().object == NULL )
00951                 return;
00952 
00953         CComObjPtr<IMgaMetaRegNode> regnode;
00954 
00955         const std::tstring &name = GetByName(attributes, _T("name"));
00956 
00957         if( GetPrevName() == _T("part") )
00958         {
00959                 CComObjPtr<IMgaMetaPart> prev;
00960                 GetPrevObj(prev);
00961                 COMTHROW( prev->get_RegistryNode(PutInBstr(name), PutOut(regnode)) );
00962         }
00963         else if( GetPrevName() == _T("regnode") )
00964         {
00965                 CComObjPtr<IMgaMetaRegNode> prev;
00966                 GetPrevObj(prev);
00967                 COMTHROW( prev->get_RegistryNode(PutInBstr(name), PutOut(regnode)) );
00968         }
00969         else
00970         {
00971                 CComObjPtr<IMgaMetaBase> prev;
00972                 GetPrevObj(prev);
00973                 COMTHROW( prev->get_RegistryNode(PutInBstr(name), PutOut(regnode)) );
00974         }
00975 
00976         ASSERT( regnode != NULL );
00977         GetCurrent().object = regnode;
00978 
00979         attributes_iterator i = attributes.begin();
00980         attributes_iterator e = attributes.end();
00981         while( i != e )
00982         {
00983                 Attr(i, _T("value"), regnode, &IMgaMetaRegNode::put_Value);
00984 
00985                 ++i;
00986         }
00987 }
00988 
00989 void CMgaMetaParser::StartConstraint(const attributes_type &attributes)
00990 {
00991         CComObjPtr<IMgaMetaConstraint> c;
00992 
00993         CComObjPtr<IMgaMetaBase> prev;
00994         GetPrevObj(prev);
00995         COMTHROW( prev->CreateConstraint(PutOut(c)) );
00996 
00997         ASSERT( c != NULL );
00998         GetCurrent().object = c;
00999 
01000         foundconstraints = true;
01001 
01002 
01003         attributes_iterator i = attributes.begin();
01004         attributes_iterator e = attributes.end();
01005         while( i != e )
01006         {
01007                 Attr(i, _T("name"), c, &IMgaMetaConstraint::put_Name);
01008                 Attr(i, _T("eventmask"), c, &IMgaMetaConstraint::put_EventMask);
01009                 Attr(i, _T("priority"), c, &IMgaMetaConstraint::put_Priority);
01010                 Attr(i, _T("defdfornamesp"), c, &IMgaMetaConstraint::SetDefinedForNamespace);
01011 
01012                 if( i->first == _T("depth") )
01013                 {
01014                         constraint_depth_enum depth;
01015                         if( i->second == _T("0") )
01016                                 depth = CONSTRAINT_DEPTH_ZERO;
01017                         else if( i->second == _T("any") )
01018                                 depth = CONSTRAINT_DEPTH_ANY;
01019                         else
01020                                 depth = CONSTRAINT_DEPTH_ONE;
01021                         COMTHROW( c->put_Depth(depth) );
01022                 }
01023                 else if( i->first == _T("type") )
01024                 {
01025                         constraint_type_enum type;
01026                         if( i->second == _T("ondemand") )
01027                                 type = CONSTRAINT_TYPE_ONDEMAND;
01028                         else if( i->second == _T("function") )
01029                                 type = CONSTRAINT_TYPE_FUNCTION;
01030                         else
01031                                 type = CONSTRAINT_TYPE_EVENTBASED;
01032                         COMTHROW( c->put_Type(type) );
01033                 }
01034 
01035                 ++i;
01036         }
01037 }
01038 
01039 void CMgaMetaParser::EndConstraint()
01040 {
01041         CComObjPtr<IMgaMetaConstraint> c;
01042 
01043         ASSERT( GetCurrent().object != NULL );
01044         COMTHROW( GetCurrent().object.QueryInterface(c) );
01045         ASSERT( c != NULL );
01046 
01047         COMTHROW( c->put_Expression(PutInBstr(GetCurrData())) );
01048 }